Sort two arrays the same way
You can sort the existing arrays, or reorganize the data.
Method 1:
To use the existing arrays, you can combine, sort, and separate them:
(Assuming equal length arrays)
var names = ["Bob","Tom","Larry"];
var ages = ["10", "20", "30"];
//1) combine the arrays:
var list = [];
for (var j = 0; j < names.length; j++)
list.push({'name': names[j], 'age': ages[j]});
//2) sort:
list.sort(function(a, b) {
return ((a.name < b.name) ? -1 : ((a.name == b.name) ? 0 : 1));
//Sort could be modified to, for example, sort on the age
// if the name is the same. See Bonus section below
});
//3) separate them back out:
for (var k = 0; k < list.length; k++) {
names[k] = list[k].name;
ages[k] = list[k].age;
}
This has the advantage of not relying on string parsing techniques, and could be used on any number of arrays that need to be sorted together.
Method 2: Or you can reorganize the data a bit, and just sort a collection of objects:
var list = [
{name: "Bob", age: 10},
{name: "Tom", age: 20},
{name: "Larry", age: 30}
];
list.sort(function(a, b) {
return ((a.name < b.name) ? -1 : ((a.name == b.name) ? 0 : 1));
});
for (var i = 0; i<list.length; i++) {
alert(list[i].name + ", " + list[i].age);
}
For the comparisons,-1 means lower index, 0 means equal, and 1 means higher index. And it is worth noting that sort()
actually changes the underlying array.
Also worth noting, method 2 is more efficient as you do not have to loop through the entire list twice in addition to the sort.
http://jsfiddle.net/ghBn7/38/
Bonus Here is a generic sort method that takes one or more property names.
function sort_by_property(list, property_name_list) {
list.sort((a, b) => {
for (var p = 0; p < property_name_list.length; p++) {
prop = property_name_list[p];
if (a[prop] < b[prop]) {
return -1;
} else if (a[prop] !== a[prop]) {
return 1;
}
}
return 0;
});
}
Usage:
var list = [
{name: "Bob", age: 10},
{name: "Tom", age: 20},
{name: "Larry", age: 30},
{name: "Larry", age: 25}
];
sort_by_property(list, ["name", "age"]);
for (var i = 0; i<list.length; i++) {
console.log(list[i].name + ", " + list[i].age);
}
Output:
- Bob, 10
- Larry, 25
- Larry, 30
- Tom, 20
How to sort two lists (which reference each other) in the exact same way
One classic approach to this problem is to use the "decorate, sort, undecorate" idiom, which is especially simple using python's built-in zip
function:
>>> list1 = [3,2,4,1, 1]
>>> list2 = ['three', 'two', 'four', 'one', 'one2']
>>> list1, list2 = zip(*sorted(zip(list1, list2)))
>>> list1
(1, 1, 2, 3, 4)
>>> list2
('one', 'one2', 'two', 'three', 'four')
These of course are no longer lists, but that's easily remedied, if it matters:
>>> list1, list2 = (list(t) for t in zip(*sorted(zip(list1, list2))))
>>> list1
[1, 1, 2, 3, 4]
>>> list2
['one', 'one2', 'two', 'three', 'four']
It's worth noting that the above may sacrifice speed for terseness; the in-place version, which takes up 3 lines, is a tad faster on my machine for small lists:
>>> %timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 3.3 us per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best of 3: 2.84 us per loop
On the other hand, for larger lists, the one-line version could be faster:
>>> %timeit zip(*sorted(zip(list1, list2)))
100 loops, best of 3: 8.09 ms per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100 loops, best of 3: 8.51 ms per loop
As Quantum7 points out, JSF's suggestion is a bit faster still, but it will probably only ever be a little bit faster, because Python uses the very same DSU idiom internally for all key-based sorts. It's just happening a little closer to the bare metal. (This shows just how well optimized the zip
routines are!)
I think the zip
-based approach is more flexible and is a little more readable, so I prefer it.
Note that when elements of list1
are equal, this approach will end up comparing elements of list2
. If elements of list2
don't support comparison, or don't produce a boolean when compared (for example, if list2
is a list of NumPy arrays), this will fail, and if elements of list2
are very expensive to compare, it might be better to avoid comparison anyway.
In that case, you can sort indices as suggested in jfs's answer, or you can give the sort a key function that avoids comparing elements of list2
:
result1, result2 = zip(*sorted(zip(list1, list2), key=lambda x: x[0]))
Also, the use of zip(*...)
as a transpose fails when the input is empty. If your inputs might be empty, you will have to handle that case separately.
C - Sort two arrays the same way
The better solution is to group the data into an array of structures, then sort that based on the desired key (i.e. the a
values):
struct my_data {
int a;
int b;
};
struct my_data data[100];
static int data_cmp(const void *a, const void *b)
{
const struct my_data *da = a, *db = b;
return da->a < db->a ? -1 : da->a > db->a;
}
qsort(data, sizeof data / sizeof *data, sizeof *data, data_cmp);
This uses qsort()
to sort, which is typically highly desirable.
How to sort two arrays by same index?
Use Array.Sort<TKey, TValue>(TKey[] keys, TValue[] items)
that accepts two input arrays, one is the array of keys, the other is the array of items to sort using those keys. Here, for you, b
is your keys and a
is your items.
Thus:
Array.Sort(b, a);
will use the keys of b
to sort the items of a
.
I want to sort
c
byb
's index ->c = {"1", "b", "u", "r", "a", "s"}
Not clear exactly what you mean. At the same time as you sort a
using b
? If so, it's easy as we can still use the above. Zip a
and c
into a single array of Tuple<int, string>
.
var d = a.Zip(c, (x, y) => Tuple.Create(x, y)).ToArray();
Then:
Array.Sort(b, d);
as above. Then extract the pieces:
a = d.Select(z => z.Item1).ToArray();
c = d.Select(z => z.Item2).ToArray();
Alternatively, if you need to sort a lot of arrays using the same set of keys:
int[] indexes = Enumerable.Range(0, b.Length).ToArray();
Array.Sort(b, indexes);
Now you can use indexes
to sort all the arrays you need. For example:
a = indexes.Select(index => a[index]).ToArray();
c = indexes.Select(index => c[index]).ToArray();
etc. as needed.
Possibly some minor coding errors here. No compiler handy.
Sorting two corresponding arrays
Rather than sort the arrays, sort the indices. I.e., you have
int arr[5]={4,1,3,6,2}
string arr1[5]={"a1","b1","c1","d1","e1"};
and you make
int indices[5]={0,1,2,3,4};
now you make a sort indices comparator that looks like this (just and idea, you'll probably have to fix it a little)
class sort_indices
{
private:
int* mparr;
public:
sort_indices(int* parr) : mparr(parr) {}
bool operator()(int i, int j) const { return mparr[i]<mparr[j]; }
}
now you can use the stl sort
std::sort(indices, indices+5, sort_indices(arr));
when you're done, the indices array will be such that arr[indices[0]]
is the first element. and likewise arr1[indices[0]]
is the corresponding pair.
This is also a very useful trick when you're trying to sort a large data object, you don't need to move the data around at every swap, just the indices.
How to sort two arrays with one being sorted based on the sorting of the other?
Pair Class could do the trick here.
import java.util.*;
public class Main
{
static class Pair implements Comparable<Pair>
{
int a1;
int a2;
Pair (int a1, int a2) //constructor
{
this.a1 = a1;
this.a2 = a2;
}
public int compareTo(Pair other) //making it only compare a2 values
{
return this.a2 - other.a2;
}
}
public static void main(String[] args)
{
int[] A1 = {1,2,3,4,5,6,7,8,9,10};
int[] A2 = {1,2,3,0,2,1,1,0,0,0};
Pair[] pairs = new Pair[A1.length];
for (int i = 0; i < pairs.length; i++)
{
pairs[i] = new Pair(A1[i], A2[i]);
}
Arrays.sort(pairs);
//printing values
for (int i = 0; i < A1.length; i++)
{
System.out.print(pairs[i].a1 + " ");
}
System.out.println();
for (int i = 0; i < A2.length; i++)
{
System.out.print(pairs[i].a2 + " ");
}
}
}
By making a Pair class that holds 2 variables a1
and a2
, you can override the compareTo
method to only compare the a2
value, so that when Arrays.sort
is called, the pairs in the Pair array will be swapped only according to the a2
values. You can then access the values in the pairs and print them out. This will produce your desired output.
Sorting multiple arrays based on one
Use a hash as your intuition was leading you to:
var scores = [2, 5, 3, 1, 4];var countries = ["Canada", "Macau", "Sweden", "France", "China"];
var score = {};for( var i=0,n=scores.length; i<n; i++){ score[scores[i]] = countries[i];}
for( var key in keys=Object.keys(score).sort() ){ var prop = keys[key]; console.log(prop, score[prop]);}
PHP - Sort Two Arrays The Same Way
http://php.net/manual/en/function.array-multisort.php
using example #1 in the reference:
$a = array('Bob', 'Sue', 'Phil', 'Jenny');
$b = array(15, 12, 13, 13);
array_multisort($a, $b);
print_r($a);
> Array
(
[0] => Bob
[1] => Jenny
[2] => Phil
[3] => Sue
)
print_r($b);
> Array
(
[0] => 15
[1] => 13
[2] => 13
[3] => 12
)
How to sort two arrays in the same way?
first make sure letters
list contain data in correct order, in your question at second position in digits
you have 1.1 and in letters
you have two, which seems a mistake to me
var letters = arrayOf("two", "one", "three")
var digits = arrayOf(2.36, 1.1, 3.0)
val x = digits.zip(letters).toMap().toSortedMap { o1, o2 -> o2.compareTo(o1)}
val keys = x.keys.toList() // [3.0, 2.36, 1.1]
val values = x.values.toList() // [three, two, one]
if you have large data set and don't want to waste memory on in-flight data structures (Pairs
, List
etc) then you can directly build a SortedMap
val x = emptyMap<Double, String>().toSortedMap{ o1, o2 -> o2.compareTo(o1)}
digits.forEachIndexed{index, value ->
x[value] = letters[index]
}
Sort two arrays based on the length of one
You could take the indices, sort them and map the values for both arrays.
var array1 = ['maximilian', 'moritz', 'hans'], array2 = [5, 1, 2000], indices = array1.map((_, i) => i); indices.sort((a, b) => array1[a].length - array1[b].length);
array1 = indices.map(i => array1[i]);array2 = indices.map(i => array2[i]);
console.log(array1);console.log(array2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Related Topics
Microsoft Cdn for Jquery or Google Cdn
Typescript: Deep Keyof of a Nested Object, with Related Type
How to Remove an Object from an Array with JavaScript
Javascript's Getdate Returns Wrong Date
Remove Characters from a String
Accessing the Content of Other Tabs in a Browser
Access to Es6 Array Element Index Inside For-Of Loop
How to Handle Circular Dependencies with Requirejs/Amd
Cross Domain Post Request Is Not Sending Cookie Ajax Jquery
How to Convert a String into a Math Operator in JavaScript
How to Remove Emoji Code Using JavaScript
Copy a Variable's Value into Another
How to Request the Garbage Collector in Node.Js to Run
Compare 2 Arrays Which Returns Difference