根据第一个排序数组的索引对第二个数组进行排序。

huangapple go评论59阅读模式
英文:

Sorting second array accordingly to the indexs of first sorted array

问题

我有两个大小相同的数组。

ArrayList<ProfileClass> array1= new ArrayList<>()
ArrayList<Double> array2= new ArrayList<>()

array1 = {b,d,a,c}
array2 = {2.0,4.0,1.0,3.0}

现在我需要按降序对array2进行排序。
Collections.sort(array2, Collections.reverseOrder());
预期结果: {4.0,3.0,2.0,1.0}

因此,在排序之前,这些值的索引与排序后的索引不同。但是,对于array2中的每个值,索引已经改变了,我希望array1也根据array2中的每个值相应地改变索引。

array1的最终预期结果: {d,c,b,a}

英文:

I have two arrays with same size.

ArrayList&lt;ProfileClass&gt; array1= new ArrayList&lt;&gt;()
ArrayList&lt;Double&gt; array2= new ArrayList&lt;&gt;()

array1 = {b,d,a,c}
array2 = {2.0,4.0,1.0,3.0}

Now I need to sort array2 in descending order.
Collections.sort(array2, Collections.reverseOrder());
Expected result: {4.0,3.0,2.0,1.0}

Therefore, indexes of these values before sorting against each value is not same as it is after sorting. However the index are changed against each value in array2, I want array1 to change indexes against each value accordingly to array2.

Final Expected result of array1: {d,c,b,a}

答案1

得分: 1

你可以通过按array2的值对索引(0、1、2、3)进行排序,并将结果映射到array1的值来获取结果。

System.out.println("array1=" + array1);
System.out.println("array2=" + array2);
ArrayList<ProfileClass> sortedArray1 = IntStream.range(0, array2.size())
    .boxed()
    .sorted(Collections.reverseOrder(Comparator.comparingDouble(i -> array2.get(i))))
    .map(i -> array1.get(i))
    .collect(Collectors.toCollection(ArrayList::new));
System.out.println("sorted array1=" + sortedArray1);

输出结果:

array1=[b, d, a, c]
array2=[2.0, 4.0, 1.0, 3.0]
sorted array1=[d, c, b, a]

或者你也可以这样做:

ArrayList<ProfileClass> sortedArray1 = IntStream.range(0, array2.size())
    .mapToObj(i -> new Object() {
        double sortKey = array2.get(i);
        ProfileClass value = array1.get(i);
    })
    .sorted(Collections.reverseOrder(Comparator.comparingDouble(obj -> obj.sortKey)))
    .map(obj -> obj.value)
    .collect(Collectors.toCollection(ArrayList::new));
英文:

You can get the result by sorting the indexes (0, 1, 2, 3) by the value of array2 and mapping the result to the value of array1.

System.out.println(&quot;array1=&quot; + array1);
System.out.println(&quot;array2=&quot; + array2);
ArrayList&lt;ProfileClass&gt; sortedArray1 = IntStream.range(0, array2.size())
    .boxed()
    .sorted(Collections.reverseOrder(Comparator.comparingDouble(i -&gt; array2.get(i))))
    .map(i -&gt; array1.get(i))
    .collect(Collectors.toCollection(ArrayList::new));
System.out.println(&quot;sorted array1=&quot; + sortedArray1);

output:

array1=[b, d, a, c]
array2=[2.0, 4.0, 1.0, 3.0]
sorted array1=[d, c, b, a]

Or you can also do like this.

ArrayList&lt;ProfileClass&gt; sortedArray1 = IntStream.range(0, array2.size())
    .mapToObj(i -&gt; new Object() {
        double sortKey = array2.get(i);
        ProfileClass value = array1.get(i);
    })
    .sorted(Collections.reverseOrder(Comparator.comparingDouble(obj -&gt; obj.sortKey)))
    .map(obj -&gt; obj.value)
    .collect(Collectors.toCollection(ArrayList::new));

答案2

得分: 0

你应该创建一个临时的双重ArrayList。并且在排序之前,你应该保留array2的索引。

期望的 tmpArrayList = {1, 3, 0, 2}

然后,使用这些索引,你可以重新创建array1。

如果你不必将array1作为链表使用,最好的解决方案是 array1 = new ProfileList[];

在这里,我想说的是,为什么这是必要的,你可以为你的profileclass对象添加另一个字段,比如 array2Place?并进行更新。我不明白你实际上想要做什么。比如,array2是否与array1有关的某些索引?

英文:

You should create a temp Double arrayList. And you should keep the indexes of array2 before sorting.

expected tmpArrayList = {1, 3, 0, 2}

then, with these indexes, you can recreate array1.

If you don't have to use array1 as linkedlist, it is better array1 = new ProfileList[]; for this solution.

Here, i want to say, why is this necessary, you can just put another field to your profileclass object such as array2Place?? and update it. I don't get what are you trying to do here actually. Such as, is array2 index of something about array1?

答案3

得分: 0

Create a Map using both arrays and get the first array (map value array 1) from the map using the key (Array 2).

//Map it
使用两个数组创建一个Map,并使用键(Array 2)从Map中获取第一个数组(map value array 1)。

//Create new array for array1
为array1创建新数组

System.out.println(array11);
打印array11

英文:

Create a Map using both arrays and get the first array (map value array 1) from the map using the key (Array 2).

//Map it
Map&lt;Double, ProfileClass&gt; map = IntStream.range(0, array2.size()).boxed()
	    .collect(Collectors.toMap(i -&gt; array2.get(i), i -&gt; array1.get(i)));
Collections.sort(array2, Collections.reverseOrder());

//Create new array for array1
List&lt;ProfileClass&gt; array11 = new ArrayList&lt;&gt;();
for (Double d : array2) {
	array11.add(map.get(d));
}

System.out.println(array11);

答案4

得分: 0

在假设两个数组(尤其是第一个数组)可能包含重复元素的情况下,我建议使用以下解决方案:

ProfileClass[] arr1 = new String[] { b,d,a,c };
double[] arr2 = new double[] { 2.0,4.0,1.0,3.0 };

List<Tuple<ProfileClass, Double>> list 
  = IntStream.range(0, arr2.length) // 创建包含所有可能索引的流
  .mapToObj(i -> new Tuple<ProfileClass, Double>(arr1[i], arr2[i])) // 按索引将两个数组合并
  .sorted((a,b) -> Double.compare(a.getItem2(), b.getItem2())) // 根据第二个数组对流进行排序
  .collect(Collectors.toList());

// 将结果写回数组
for (int i = 0; i < arr1.length; i++) {
  arr1[i] = list.get(i).getItem1();
  arr2[i] = list.get(i).getItem2();
}

这里的Tuple类定义如下:

public class Tuple<T1, T2> {
  private T1 item1;
  private T2 item2;

  public Tuple(T1 item1, T2 item2) {
      this.item1 = item1;
      this.item2 = item2;
  }

  public T1 getItem1() { return item1; }
  public T2 getItem2() { return item2; }
}
英文:

On the assumption that both arrays (especially the first) can contain duplicates I would suggest the following solution

ProfileClass[] arr1 = new String[] { b,d,a,c };
double[] arr2 = new double[] { 2.0,4.0,1.0,3.0 };

List&lt;Tuple&lt;ProfileClass, Double&gt;&gt; list 
  = IntStream.range(0, arr2.length) // create a stream of all possible indexes
  .mapToObj(i -&gt; new Tuple&lt;ProfileClass, Double&gt;(arr1[i], arr2[i])) // zip the two arrays by the index
  .sorted((a,b) -&gt; Double.compare(a.getItem2(), b.getItem2())) // sort the stream according to the second array
  .collect(Collectors.toList());

// write the result back to the array
for (int i = 0; i &lt; arr1.length; i++) {
  arr1[i] = list.get(i).getItem1();
  arr2[i] = list.get(i).getItem2();
}

here the class Tuple is defined as:

public class Tuple&lt;T1, T2&gt; {
  private T1 item1;
  private T2 item2;

  public Tuple(T1 item1, T2 item2) {
      this.item1 = item1;
      this.item2 = item2;
  }

  public T1 getItem1() { return item1; }
  public T2 getItem2() { return item2; }
}

答案5

得分: 0

简单易用的TreeMap,用于快速排序订单。

TreeMap<Double, ProfileClass> map = new TreeMap<>();
for (int i = 0; i < array1.size(); i++) {
    map.put(array2.get(i), array1.get(i));
}
final Collection<ProfileClass> sortedArray = map.descendingMap().values();
System.out.println(sortedArray);
英文:

Simple to use TreeMap for sorting orders quickly.

TreeMap&lt;Double, ProfileClass&gt; map = new TreeMap&lt;&gt;();
    for (int i = 0; i &lt; array1.size(); i++) {
        map.put(array2.get(i), array1.get(i));
    }
    final Collection&lt; ProfileClass&gt; sortedArray = map.descendingMap().values();
    System.out.println(sortedArray);

答案6

得分: 0

如果您能够创建一个同时保存两个值的类,只需要一个排序。

如果这不可能,请检查来自@NiravHR的解决方案,似乎是合理的。

public class Tester {

    static class Holder implements Comparable<Holder> {

        private Holder(String letter, Double value) {
            this.letter = letter;
            this.value = value;
        }

        String letter;

        Double value;

        static Holder of(String letter, Double value) {
            return new Holder(letter, value);
        }

        @Override
        public int compareTo(Holder o) {
            return value.compareTo(o.value);
        }

        @Override
        public String toString() {
            return String.valueOf(this.letter);
        }
    }

    public static void main(String[] args) {

        List<Holder> data = Arrays.asList(
                Holder.of("b", 2.0),
                Holder.of("d", 4.0),
                Holder.of("a", 1.0),
                Holder.of("c", 3.0)
        );
        Collections.sort(data, Collections.reverseOrder());

        System.out.println(data);
    }
}
英文:

If you are able to have class which holds both values only one sort is required.

In case this is not possible please check the solution from @NiravHR, seems legit.

public class Tester {

    static class Holder implements  Comparable&lt;Holder&gt; {

        private Holder(String letter, Double value){
            this.letter = letter;
            this.value  = value;
        }

        String letter;

        Double value;

        static Holder of(String letter, Double value){
            return new Holder(letter,value);
        }

        @Override
        public int compareTo(Holder o) {
            return value.compareTo(o.value);
        }

        @Override
        public String toString() {
            return String.valueOf(this.letter);
        }
    }


    public static void main(String[] args) {

       List&lt;Holder&gt; data = Arrays.asList(
         Holder.of(&quot;b&quot;,2.0),
         Holder.of(&quot;d&quot;,4.0),
         Holder.of(&quot;a&quot;,1.0),
         Holder.of(&quot;c&quot;,3.0)
       );
       Collections.sort(data, Collections.reverseOrder());


       System.out.println(data);
    }
}

huangapple
  • 本文由 发表于 2020年7月29日 20:37:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63153789.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定