Sorting an array related to another array

I have two arrays, x and y, where y is the value of the tens of every element in x. Now, I want to sort y. But, the order of y will be different of x's. So, I can't tell after sorting which element in y was related to, for instance, x[0].

I want a "double sorting" maybe.


Array.Sort has an overload that accepts two arrays; one for the keys, and one for the items. The items of both are sorted according to the keys array:

int[] keys = { 1, 4, 3, 2, 5 };
string[] items = { "abc", "def", "ghi", "jkl", "mno" };
Array.Sort(keys, items);
foreach (int key in keys) {
    Console.WriteLine(key); // 1, 2, 3, 4, 5
}
foreach (string item in items) {
    Console.WriteLine(item); // abc, jkl, ghi, def, mno
}

So in your case, it sounds like you want:

Array.Sort(y,x); // or Sort(x,y); - it isn't  100% clear

How about?

var selectedArr = new int[] { 1, 3, 5, 7, 9 };
var unorderArr = new int[] { 9, 7, 5, 3, 1 };
var orderedArr = unorderArr.OrderBy(o => selectedArr.IndexOf(o));

If y is always the tens value of x, y probably shouldn't exist - you should probably just calculate it's value directly off of x when needed.

In general, sorting parallel arrays is only possible (without hand rolling a sort algorithm) when the sort algorithm takes a custom "swap" function, which you can implement in terms of swapping elements in both arrays simultaneously. std::sort in C++ and qsort in C don't allow this.

Also in the general case, consider a single array where the element is a pair of items, rather than a parallel array for each item. This makes using "standard" algorithms easier.


If we have two arrays of complex objects and want to sort them according to one of the two arrays then we can use the next approach:

// We want to sort "people" array by "Name" and
// accordingly to it reorder "countries" array.
Person[] people = new Person[]
{
    new Person {Name = "Fill"},
    new Person {Name = "Will"},
    new Person {Name = "Bill"},
};

Country[] countries = new Country[]
{
    new Country {Name = "Canada"},
    new Country {Name = "UK"},
    new Country {Name = "USA"}
};

// Here we sort "people" array, but together with each "Person"
// in sorted array we store its "index" in unsorted array. Then we
// will use this "index" to reorder items in "countries" array.
var sorted = people
    .Select((person, index) => new {person, index})
    .OrderBy(x => x.person.Name)
    .ToArray();

// Here "people" array is sorted by "Name", and
// "contries" array is reordered accordingly to it.
people = sorted.Select(x => x.person).ToArray();
countries = sorted.Select(x => countries[x.index]).ToArray();

Another approach is to use overload of the method Array.Sort with IComparer. At first we should implement IComparer:

private class PeopleComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        return x.Name.CompareTo(y.Name);
    }
}

And then we can sort two our arrays:

Array.Sort(people, countries, new PeopleComparer());

Here is complete sample that demonstrates these two approaches.