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

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

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的值来获取结果。

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

输出结果:

  1. array1=[b, d, a, c]
  2. array2=[2.0, 4.0, 1.0, 3.0]
  3. sorted array1=[d, c, b, a]

或者你也可以这样做:

  1. ArrayList<ProfileClass> sortedArray1 = IntStream.range(0, array2.size())
  2. .mapToObj(i -> new Object() {
  3. double sortKey = array2.get(i);
  4. ProfileClass value = array1.get(i);
  5. })
  6. .sorted(Collections.reverseOrder(Comparator.comparingDouble(obj -> obj.sortKey)))
  7. .map(obj -> obj.value)
  8. .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.

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

output:

  1. array1=[b, d, a, c]
  2. array2=[2.0, 4.0, 1.0, 3.0]
  3. sorted array1=[d, c, b, a]

Or you can also do like this.

  1. ArrayList&lt;ProfileClass&gt; sortedArray1 = IntStream.range(0, array2.size())
  2. .mapToObj(i -&gt; new Object() {
  3. double sortKey = array2.get(i);
  4. ProfileClass value = array1.get(i);
  5. })
  6. .sorted(Collections.reverseOrder(Comparator.comparingDouble(obj -&gt; obj.sortKey)))
  7. .map(obj -&gt; obj.value)
  8. .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).

  1. //Map it
  2. Map&lt;Double, ProfileClass&gt; map = IntStream.range(0, array2.size()).boxed()
  3. .collect(Collectors.toMap(i -&gt; array2.get(i), i -&gt; array1.get(i)));
  4. Collections.sort(array2, Collections.reverseOrder());
  5. //Create new array for array1
  6. List&lt;ProfileClass&gt; array11 = new ArrayList&lt;&gt;();
  7. for (Double d : array2) {
  8. array11.add(map.get(d));
  9. }
  10. System.out.println(array11);

答案4

得分: 0

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

  1. ProfileClass[] arr1 = new String[] { b,d,a,c };
  2. double[] arr2 = new double[] { 2.0,4.0,1.0,3.0 };
  3. List<Tuple<ProfileClass, Double>> list
  4. = IntStream.range(0, arr2.length) // 创建包含所有可能索引的流
  5. .mapToObj(i -> new Tuple<ProfileClass, Double>(arr1[i], arr2[i])) // 按索引将两个数组合并
  6. .sorted((a,b) -> Double.compare(a.getItem2(), b.getItem2())) // 根据第二个数组对流进行排序
  7. .collect(Collectors.toList());
  8. // 将结果写回数组
  9. for (int i = 0; i < arr1.length; i++) {
  10. arr1[i] = list.get(i).getItem1();
  11. arr2[i] = list.get(i).getItem2();
  12. }

这里的Tuple类定义如下:

  1. public class Tuple<T1, T2> {
  2. private T1 item1;
  3. private T2 item2;
  4. public Tuple(T1 item1, T2 item2) {
  5. this.item1 = item1;
  6. this.item2 = item2;
  7. }
  8. public T1 getItem1() { return item1; }
  9. public T2 getItem2() { return item2; }
  10. }
英文:

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

  1. ProfileClass[] arr1 = new String[] { b,d,a,c };
  2. double[] arr2 = new double[] { 2.0,4.0,1.0,3.0 };
  3. List&lt;Tuple&lt;ProfileClass, Double&gt;&gt; list
  4. = IntStream.range(0, arr2.length) // create a stream of all possible indexes
  5. .mapToObj(i -&gt; new Tuple&lt;ProfileClass, Double&gt;(arr1[i], arr2[i])) // zip the two arrays by the index
  6. .sorted((a,b) -&gt; Double.compare(a.getItem2(), b.getItem2())) // sort the stream according to the second array
  7. .collect(Collectors.toList());
  8. // write the result back to the array
  9. for (int i = 0; i &lt; arr1.length; i++) {
  10. arr1[i] = list.get(i).getItem1();
  11. arr2[i] = list.get(i).getItem2();
  12. }

here the class Tuple is defined as:

  1. public class Tuple&lt;T1, T2&gt; {
  2. private T1 item1;
  3. private T2 item2;
  4. public Tuple(T1 item1, T2 item2) {
  5. this.item1 = item1;
  6. this.item2 = item2;
  7. }
  8. public T1 getItem1() { return item1; }
  9. public T2 getItem2() { return item2; }
  10. }

答案5

得分: 0

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

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

Simple to use TreeMap for sorting orders quickly.

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

答案6

得分: 0

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

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

  1. public class Tester {
  2. static class Holder implements Comparable<Holder> {
  3. private Holder(String letter, Double value) {
  4. this.letter = letter;
  5. this.value = value;
  6. }
  7. String letter;
  8. Double value;
  9. static Holder of(String letter, Double value) {
  10. return new Holder(letter, value);
  11. }
  12. @Override
  13. public int compareTo(Holder o) {
  14. return value.compareTo(o.value);
  15. }
  16. @Override
  17. public String toString() {
  18. return String.valueOf(this.letter);
  19. }
  20. }
  21. public static void main(String[] args) {
  22. List<Holder> data = Arrays.asList(
  23. Holder.of("b", 2.0),
  24. Holder.of("d", 4.0),
  25. Holder.of("a", 1.0),
  26. Holder.of("c", 3.0)
  27. );
  28. Collections.sort(data, Collections.reverseOrder());
  29. System.out.println(data);
  30. }
  31. }
英文:

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.

  1. public class Tester {
  2. static class Holder implements Comparable&lt;Holder&gt; {
  3. private Holder(String letter, Double value){
  4. this.letter = letter;
  5. this.value = value;
  6. }
  7. String letter;
  8. Double value;
  9. static Holder of(String letter, Double value){
  10. return new Holder(letter,value);
  11. }
  12. @Override
  13. public int compareTo(Holder o) {
  14. return value.compareTo(o.value);
  15. }
  16. @Override
  17. public String toString() {
  18. return String.valueOf(this.letter);
  19. }
  20. }
  21. public static void main(String[] args) {
  22. List&lt;Holder&gt; data = Arrays.asList(
  23. Holder.of(&quot;b&quot;,2.0),
  24. Holder.of(&quot;d&quot;,4.0),
  25. Holder.of(&quot;a&quot;,1.0),
  26. Holder.of(&quot;c&quot;,3.0)
  27. );
  28. Collections.sort(data, Collections.reverseOrder());
  29. System.out.println(data);
  30. }
  31. }

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:

确定