按照另一个数组中指定的顺序排序数组

时间:2018-06-19 09:49:16

标签: c# arrays list sorting

我有一个键值对列表,我想根据另一个数组中指定的顺序进行排序。

var requiredOrder = new String[] { "PH", "HH", "PR", "SR", "UN", "UD", "WD", "WE", "OT" };


        var listToBeSorted = new List<KeyValuePair<string, string>>() {
            new KeyValuePair<string, string>("A","PR"),
            new KeyValuePair<string, string>("B","PH"),
            new KeyValuePair<string, string>("C","HH"),
            new KeyValuePair<string, string>("D","WD"),
            new KeyValuePair<string, string>("E","OT"),
            new KeyValuePair<string, string>("F","UN"),
            .....
        };

'listToBeSorted'实际上是我为下拉列表提取的集合,需要根据'requiredOrder'数组按值排序。

5 个答案:

答案 0 :(得分:2)

您可以使用requiredOrder

Array.IndexOf()数组中的项目索引进行排序
listToBeSorted = listToBeSorted.OrderBy(x => Array.IndexOf(requiredOrder, x.Value)).ToList();

答案 1 :(得分:2)

考虑到要排序的列表只有唯一身份

O(N ^ 2)方法的性能优于带有IndexOf的OrderBy,后者是NLogN * N =(N ^ 2)LogN(因为indexof,隐藏N,在排序的每一步执行),看到代码中的评论

var sortedList = new List<KeyValuePair<string, string>>();

for (int i = 0; i < requiredOrder.Length; i++) { // "i" spares indexof.
    for (int j = 0, l = listToBeSorted.Count; j < l; j++) {
        if (requiredOrder[i].Equals(listToBeSorted[j].Value)) {
            sortedList.Add(listToBeSorted[j]);
            //might as well Remove from listToBeSorted to decrease complexity.
            //listToBeSorted.RemoveAt(j);
            break;
        }
    }
}

不是最经典的代码,但可以进一步改进。

如果从listToBeSorted中删除(并调整循环索引),复杂性将倾向于NLogN(准确,仍为1/2 N ^ 2),空间复杂度为“0附加”。

答案 2 :(得分:1)

我认为根本不需要任何排序。

var requiredOrder = new String[] { "PH", "HH", "PR", "SR", "UN", "UD", "WD", "WE", "OT" };

var listToBeSorted = new List<KeyValuePair<string, string>>() {
    new KeyValuePair<string, string>("A","PR"),
    new KeyValuePair<string, string>("B","PH"),
    new KeyValuePair<string, string>("C","HH"),
    new KeyValuePair<string, string>("D","WD"),
    new KeyValuePair<string, string>("E","OT"),
    new KeyValuePair<string, string>("F","UN"),
    .....
};

只需将listToBeSorted转换为查找表,然后在迭代requiredOrder时抓取此表中的所有对象:

var lookup = listToBeSorted.ToLookup(kvp => kvp.Value);
var result =
    from key in requiredOrder
    from obj in lookup[key]
    select obj;

答案 3 :(得分:1)

我喜欢Lasse的答案,但它甚至可能有点整洁。试试这个:

var requiredOrder = new String[] { "PH", "HH", "PR", "SR", "UN", "UD", "WD", "WE", "OT" };

var listToBeSorted = new List<KeyValuePair<string, string>>()
{
    new KeyValuePair<string, string>("A","PR"),
    new KeyValuePair<string, string>("B","PH"),
    new KeyValuePair<string, string>("C","HH"),
    new KeyValuePair<string, string>("D","WD"),
    new KeyValuePair<string, string>("E","OT"),
    new KeyValuePair<string, string>("F","UN"),
};

var lookup = listToBeSorted.ToLookup(x => x.Value);

var sorted =
    from x in requiredOrder
    from y in lookup[x]
    select y;

这给出了:

sorted

答案 4 :(得分:0)

这是另一种方法:

  1. 创建与要排序的数组长度相同的索引数组。
  2. 使用Array.Sort(Array keys, Array items)将索引排序为正确的顺序。
  3. 使用索引数组以所需顺序访问列表。

这是示例代码-与上述算法中的步骤相对应的行分别带有(1),(2)和(3):

using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            var requiredOrder = new [] { "PH", "HH", "PR", "SR", "UN", "UD", "WD", "WE", "OT" };

            var listToBeSorted = new List<KeyValuePair<string, string>>() {
                new KeyValuePair<string, string>("A", "PR"),
                new KeyValuePair<string, string>("B", "PH"),
                new KeyValuePair<string, string>("C", "HH"),
                new KeyValuePair<string, string>("D", "WD"),
                new KeyValuePair<string, string>("E", "OT"),
                new KeyValuePair<string, string>("F", "UN"),
                new KeyValuePair<string, string>("G", "UD"),
                new KeyValuePair<string, string>("H", "WE"),
                new KeyValuePair<string, string>("I", "SR")
            };

            int[] indices = Enumerable.Range(0, requiredOrder.Length).ToArray(); // (1)

            Array.Sort(requiredOrder, indices); // (2)

            foreach (var index in indices) // (3)
            {
                Console.WriteLine(listToBeSorted[index].Key);
            }
        }
    }
}