根据选定的列表订购几个同步列表

时间:2015-01-29 11:45:43

标签: c# .net linq

说我在c#中有两个列表如下:

  • X,Y
  • 0.2,5.4
  • 0.6,4.1
  • 0.9,6.7
  • 10.58,45.7
  • -1.54,-7.02
  • 6.5,6.66

现在,我想订购X的列表,但我希望Y的列表与X的重新排序同步。

重新排序的列表如下所示:

  • X,Y
  • -1.54,-7.02
  • 0.2,5.4
  • 0.6,4.1
  • 0.9,6.7
  • 6.5,6.66
  • 10.58,45.7

使用LINQ的任何方式吗?

由于

1 个答案:

答案 0 :(得分:1)

<强> 1。 Array.Sort<TKey, TValue>(keys, value)方法

如果您的列表实际上是System.Array,或者由于ToArray来电而您不关心其他一些复制,那么最简单的方法是使用Array.Sort<TKey, TValue>(keys, value)方法

public static IList<Double> GetKeys()
{
    return new Double[] 
    {
        0.2,
        0.6, 
        0.9,
        10.58,
        -1.54,
        6.5
    }; 
}

public static IList<Double> GetValues()
{
    return new Double[]
    {
        5.4,
        4.1,
        6.7,
        45.7,
        -7.02,
        6.66
    };
}


public static void Print<T>(IEnumerable<T> items)
{
    if (items == null)
        throw new ArgumentNullException("items");

    foreach (var item in items)
    {
        Console.WriteLine(item);
    }
}

public static void PrintKeyValues<TKey, TValue>(IEnumerable<TKey> keys, IEnumerable<TValue> values)
{
    if (keys == null)
        throw new ArgumentNullException("keys");
    if (values == null)
        throw new ArgumentNullException("values");

    var pairs = keys
        .Zip(values,
            (key, value) =>
                String.Format("[{0}] = {1}", key, value));

    Print(pairs);
} 

static void Main(string[] args)
{
    var keys = GetKeys();
    var values = GetValues();

    Console.WriteLine("Before");
    PrintKeyValues(keys, values);

    Console.WriteLine();
    Console.WriteLine("After");

    var keysArray = keys.ToArray();
    var valuesArray = values.ToArray();
    Array.Sort(keysArray, valuesArray);

    PrintKeyValues(keysArray, valuesArray);

    Console.ReadKey();
}

<强> 2。几乎纯粹的LINQ

如果您需要LINQ解决方案,那么您显然没有过多复制的问题。因此,您必须对一个数组进行排序,同时使用How to get index using LINQ?保留索引,然后将相关数组洗牌:

public static T[] ShuffleFromIndices<T>(this IList<T> items, IList<Int32> indices)
{
    if (items == null)
        throw new ArgumentNullException("items");
    if (indices == null)
        throw new ArgumentNullException("indices");
    if (items.Count != indices.Count)
        throw new ArgumentException("items and indices have different lengths");

    T[] result = new T[items.Count];

    for (int i = 0; i < items.Count; i++)
    {
        var shuffleIndex = indices[i];

        result[i] = items[shuffleIndex];
    }

    return result;
}

public static Tuple<TKey[], TValue[]> SortNotInPlace<TKey, TValue>(IList<TKey> keys, IList<TValue> values)
{
    if (keys == null)
        throw new ArgumentNullException("keys");
    if (values == null)
        throw new ArgumentNullException("values");
    if (keys.Count != values.Count)
        throw new ArgumentException("Keys and values have different lengths");

    var sortedKeysWithIndices = keys
        .Select((key, index) =>
            new { key, index })
        .OrderBy(keyIndex => keyIndex.key);

    var shuffleIndices = sortedKeysWithIndices
        .Select(keyIndex => keyIndex.index)
        .ToArray();

    var sortedValues = values.ShuffleFromIndices(shuffleIndices);

    var sortedKeys = sortedKeysWithIndices
            .Select(keyIndex => keyIndex.key)
            .ToArray();

    return new Tuple<TKey[], TValue[]>(sortedKeys,
        sortedValues);
}

static void Main(string[] args)
{
    var keys = GetKeys();
    var values = GetValues();

    Console.WriteLine("Before");
    PrintKeyValues(keys, values);


    Console.WriteLine();
    Console.WriteLine("With LINQ");

    var sorted = SortNotInPlace(keys, values);
    var sortedKeys = sorted.Item1;
    var sortedValues = sorted.Item2;
    PrintKeyValues(sortedKeys, sortedValues);

    Console.ReadKey();            
}

第3。高性能

如果你真的关心性能并且不需要额外的内存就地排序,那么你必须实现自己的Sort方法,同步对这两个列表进行排序。