如何从JSON数组中获取随机对象

时间:2020-11-29 20:10:38

This JSONAray:

这个JSONAray:

"cows": [
    {
      "age": 972,
      "name": "Betty"
      "status": "publish",
      "sticky": "pregnant"
    },
    {
      "age": 977,
      "name"; "Kate"
      "status": "publish",
      "sticky": "heat"
    },
    {
      "age": 959,
      "name": "Julie"
      "site_age": 63178480,
      "sticky": "Nursing"
    },
    ...
 }

that contains 20 objects. What I wanted is this: get 3 random objects out of the 20. And the ages of any of the three won't be a certain number say 961.

包含20个对象。我想要的是:从20个中获取3个随机对象。这三个中的任何一个的年龄都不会是961。

Currently this what I am doing:

目前我正在做的事情:

private void parseCowsReq(JSONObject array) {
         try {
             for (int i = 0; i < 3; i++) {
                 int randumNum = getRandomCow(array);
                 JSONObject jsonObject = array.getJSONObject(randumNum);
                 String cowName = jsonObject.getString("name");
                 String cowStatus = jsonObject.getString("status");
                 Log.d(TAG, "Cow name is " + cowName + "cow Status is " + cowStatus);
             }

         } catch (JSONException e) {
             e.printStackTrace();
         }
  }

  private int getRandomCow(JSONArray jsonArray) {
          int length = jsonArray.length();
          int[] array;
          array = new int[length-1];
          int rnd = new Random().nextInt(array.length);
          return array[rnd];
  }

There are of issues with this code.

这段代码存在一些问题。

  1. I don't know how to ensure that the object gotten in line JSONObject jsonObject = array.getJSONObject(randumNum); won't have an age of 961
  2. 我不知道如何确保对象获得JSONObject jsonObject = array.getJSONObject(randumNum);不会有961岁
  3. The random number gotten is always 0

    获得的随机数始终为0

    Please do you have any idea how this can be done?

    请问你有什么想法吗?

3 个解决方案

#1


2  

you can do it with this:

你可以这样做:

public ArrayList<Integer> getRandomObject(JSONArray jsonArray, int indexesWeeNeed){
    Random rn = new Random();
    Set<Integer> generated = new LinkedHashSet<>();
    while(generated.size() < indexesWeeNeed){
        int index = rn.nextInt(10);
        JSONObject jsonObject = (JSONObject) jsonArray.get(index);
        int age = jsonObject.getInt("age");
        if(age<961) {
            generated.add(index);
        }
    }
    ArrayList<Integer> arrayList = new ArrayList<>();
    arrayList.addAll(generated);
    return arrayList;
}

#2


0  

One part that's messed up is when you call
Random().nextInt(array.length);
array.length is the new array you just created. You need to perform the function on the existing array:
Random().nextInt(jsonArray)
to get a random number other than zero.

As for ensuring you don't get a certain age, I'd suggest breaking up the code to not call the getRandomCow(array) function inside of the for loop. When you retrieve a cow, check the name doesn't match, check the age, and if it works, keep it. If not get another cow.

搞乱的一部分就是调用Random()。nextInt(array.length); array.length是刚刚创建的新数组。您需要在现有数组上执行该函数:Random()。nextInt(jsonArray)以获取除零之外的随机数。至于确保你没有达到一定的年龄,我建议分解代码,不要在for循环中调用getRandomCow(数组)函数。检索奶牛时,检查名称是否不匹配,检查年龄,如果有效,请保留。如果没有另一头牛。

#3


0  

Well firstly, load the objects:

首先,加载对象:

JSONArray array = /* your array */;

Next, we need a method to retrieve 3 unique objects from the JSONArray (which is actually a List). Let's shuffle the indexes of the json array, so that we don't end up having to repeatedly generate duplicates:

接下来,我们需要一个方法从JSONArray(实际上是List)中检索3个唯一对象。让我们对json数组的索引进行洗牌,这样我们就不必重复生成重复项了:

public Stream<JSONObject> randomObjects(JSONArray array, int amount) {
    if (amount > array.size()) {
        //error out, null, return array, whatever you desire
        return array;
    }
    List<Integer> indexes = IntStream.range(0, array.size()).collect(Collectors.toList());
    //random, but less time generating them and keeping track of duplicates
    Collections.shuffle(indexes);
    Set<Integer> back = new HashSet<>();
    Iterator<Integer> itr = indexes.iterator();
    while (back.size() < amount && itr.hasNext()) {
        int val = itr.next();
        if (array.get(val).getInt("age") != 961) { //or any other predicates
            back.add(val);
        }
    }
    return back.stream().map(array::get);
}

Using this, we can select the three objects from the list and utilize them how we wish:

使用它,我们可以从列表中选择三个对象并按照我们的意愿使用它们:

randomObjects(array, 3).map(o -> o.getInt("age")).forEach(System.out::println);
//972
//977
//952

When I said "or any other predicates, you can pass those as well via the method:

当我说“或任何其他谓词时,你也可以通过这个方法传递它们:

public Stream<JSONObject> randomObjects(..., Predicate<Integer> validObject) {
    //...
    int val = itr.next();
    if (validObject.test(val)) {
        back.add(val);
    }
    //...
}

Which would mean you could change the blacklisting per method call:

这意味着您可以更改每个方法调用的黑名单:

Stream<JSONObject> random = randomObjects(array, 3, val -> array.get(val).getInt("age") != 961);

#1


2  

you can do it with this:

你可以这样做:

public ArrayList<Integer> getRandomObject(JSONArray jsonArray, int indexesWeeNeed){
    Random rn = new Random();
    Set<Integer> generated = new LinkedHashSet<>();
    while(generated.size() < indexesWeeNeed){
        int index = rn.nextInt(10);
        JSONObject jsonObject = (JSONObject) jsonArray.get(index);
        int age = jsonObject.getInt("age");
        if(age<961) {
            generated.add(index);
        }
    }
    ArrayList<Integer> arrayList = new ArrayList<>();
    arrayList.addAll(generated);
    return arrayList;
}

#2


0  

One part that's messed up is when you call
Random().nextInt(array.length);
array.length is the new array you just created. You need to perform the function on the existing array:
Random().nextInt(jsonArray)
to get a random number other than zero.

As for ensuring you don't get a certain age, I'd suggest breaking up the code to not call the getRandomCow(array) function inside of the for loop. When you retrieve a cow, check the name doesn't match, check the age, and if it works, keep it. If not get another cow.

搞乱的一部分就是调用Random()。nextInt(array.length); array.length是刚刚创建的新数组。您需要在现有数组上执行该函数:Random()。nextInt(jsonArray)以获取除零之外的随机数。至于确保你没有达到一定的年龄,我建议分解代码,不要在for循环中调用getRandomCow(数组)函数。检索奶牛时,检查名称是否不匹配,检查年龄,如果有效,请保留。如果没有另一头牛。

#3


0  

Well firstly, load the objects:

首先,加载对象:

JSONArray array = /* your array */;

Next, we need a method to retrieve 3 unique objects from the JSONArray (which is actually a List). Let's shuffle the indexes of the json array, so that we don't end up having to repeatedly generate duplicates:

接下来,我们需要一个方法从JSONArray(实际上是List)中检索3个唯一对象。让我们对json数组的索引进行洗牌,这样我们就不必重复生成重复项了:

public Stream<JSONObject> randomObjects(JSONArray array, int amount) {
    if (amount > array.size()) {
        //error out, null, return array, whatever you desire
        return array;
    }
    List<Integer> indexes = IntStream.range(0, array.size()).collect(Collectors.toList());
    //random, but less time generating them and keeping track of duplicates
    Collections.shuffle(indexes);
    Set<Integer> back = new HashSet<>();
    Iterator<Integer> itr = indexes.iterator();
    while (back.size() < amount && itr.hasNext()) {
        int val = itr.next();
        if (array.get(val).getInt("age") != 961) { //or any other predicates
            back.add(val);
        }
    }
    return back.stream().map(array::get);
}

Using this, we can select the three objects from the list and utilize them how we wish:

使用它,我们可以从列表中选择三个对象并按照我们的意愿使用它们:

randomObjects(array, 3).map(o -> o.getInt("age")).forEach(System.out::println);
//972
//977
//952

When I said "or any other predicates, you can pass those as well via the method:

当我说“或任何其他谓词时,你也可以通过这个方法传递它们:

public Stream<JSONObject> randomObjects(..., Predicate<Integer> validObject) {
    //...
    int val = itr.next();
    if (validObject.test(val)) {
        back.add(val);
    }
    //...
}

Which would mean you could change the blacklisting per method call:

这意味着您可以更改每个方法调用的黑名单:

Stream<JSONObject> random = randomObjects(array, 3, val -> array.get(val).getInt("age") != 961);