Loai Abdelhalim
Loai Abdelhalim

Reputation: 1967

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.

Upvotes: 37

Views: 31221

Answers (4)

Iliar Turdushev
Iliar Turdushev

Reputation: 5213

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.

Upvotes: 2

Johnny
Johnny

Reputation: 444

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));

Upvotes: 5

Marc Gravell
Marc Gravell

Reputation: 1062600

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

Upvotes: 83

Terry Mahaffey
Terry Mahaffey

Reputation: 11981

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.

Upvotes: 1

Related Questions