Sort two arrays (values, keys), and then sort the keys

I have something that seems like a simple problem, but I still can not understand.

Let's say I have two arrays:

int[] values = {10,20,20,10,30};
int[] keys = {1,2,3,4,5};

Array.Sort(values,keys);

Then the arrays will look like this:

values = {10,10,20,20,30};
keys = {4,1,2,3,5};

Now I want to make the keys also sort by second priority, so the key array looked like this:

keys = {1,4,2,3,5};

Note that the values ​​1 and 4 are switched and the order of the array of values ​​does not change.

+3
source share
5 answers

If you don't need β€œin-place sorting,” I suggest using OrderBy:

var sortedPairs = values.Select((x, i) => new { Value = x, Key = keys[i] })
                        .OrderBy(x => x.Value)
                        .ThenBy(x => x.Key)
                        .ToArray(); // this avoids sorting 2 times...
int[] sortedValues = sortedPairs.Select(x => x.Value).ToArray();
int[] sortedKeys = sortedPairs.Select(x => x.Key).ToArray();

// Result:
// sortedValues = {10,10,20,20,30};
// sortedKeys = {1,4,2,3,5};
+6
source

, . . /, , .

: , - , , . , . , .

+1

Array.Sort(, ) Comparer . Comparer, , , Comparer Array.Sort.

+1

, . , , .

. . , , .

However, for completeness, I think it would be useful to also indicate that arrays can be sorted "by proxy." That is, create a new array that is only an index of the source arrays and sorts this array. After sorting the index array, you can use this array to directly access the source data, or you can use this array to then copy the original data into new sorted arrays.

For instance:

static void Main(string[] args)
{
    int[] values = { 10, 20, 20, 10, 30 };
    int[] keys = { 1, 2, 3, 4, 5 };

    int[] indexes = Enumerable.Range(0, values.Length).ToArray();

    Array.Sort(indexes, (i1, i2) => Compare(i1, i2, values, keys));

    // Use the index array directly to access the original data
    for (int i = 0; i < values.Length; i++)
    {
        Console.WriteLine("{0}: {1}", values[indexes[i]], keys[indexes[i]]);
    }

    Console.WriteLine();

    // Or go ahead and copy the old data into new arrays using the new order
    values = OrderArray(values, indexes);
    keys = OrderArray(keys, indexes);

    for (int i = 0; i < values.Length; i++)
    {
        Console.WriteLine("{0}: {1}", values[i], keys[i]);
    }
}

private static int Compare(int i1, int i2, int[] values, int[] keys)
{
    int result = values[i1].CompareTo(values[i2]);

    if (result == 0)
    {
        result = keys[i1].CompareTo(keys[i2]);
    }

    return result;
}

private static int[] OrderArray(int[] values, int[] indexes)
{
    int[] result = new int[values.Length];

    for (int i = 0; i < values.Length; i++)
    {
        result[i] = values[indexes[i]];
    }

    return result;
}
0
source

Source: https://habr.com/ru/post/1777552/


All Articles