按给定的排序顺序收集订单

时间:2017-03-10 13:13:12

标签: c# sorting icomparer

我有一个字符串列表,我想按特定顺序带来。让我们说该列表包含随机数量的字符串" A"," B"和" C"。我有另一个包含排序顺序的字符串列表。

例如: 输入:

  1. " A"

  2. " A"

  3. " C"

  4. " B"

  5. " B"

  6. " C"

  7. 排序顺序列表:

    1. " A"
    2. " B"
    3. " C"
    4. 我想订购此List,输出如下所示:

      1. " A"
      2. " B"
      3. " C"
      4. " A"
      5. " B"
      6. " C"
      7. 另一个例子:

        输入:

        1. " A"
        2. " A"
        3. " C"
        4. " B"
        5. " C"
        6. 排序顺序列表:

          1. " A"
          2. " C"
          3. " B"
          4. 输出应如下所示:

            1. " A"
            2. " C"
            3. " B"
            4. " A"
            5. " C"
            6. 注意:为了简单起见,我选择了A,B和C,所以在我的实际应用中,我无法使用任何字母顺序。

              有没有办法达到预期的效果?我把头包裹了好几天,并没有找到解决方案。我试图实现IComparer,但我正在努力克服compare - method的条件。

2 个答案:

答案 0 :(得分:2)

我认为这符合您的需求:

        var list = new List<string> { "A", "B", "E", "A", "E", "A", "B", "E", "C", "B", "A", "D", "B", "E" };
        var sortOrder = new List<string> { "F", "E", "C", "A", "B", "D" };

        var resultSets = new List<List<string>> ();
        for (int i = 0; i < sortOrder.Count(); i++)
        {
            var currentLetter = sortOrder[i];
            for (int j = 0; j < list.Count(x=> x == currentLetter); j++)
            {
                if(resultSets.Count() < j + 1)
                {
                    resultSets.Add(new List<string>());
                }
                resultSets[j].Add(currentLetter);
            }
        }
        var result = string.Join(", ", resultSets.SelectMany(x => x));
        Console.WriteLine($"Results: { result}");

答案 1 :(得分:0)

虽然接受的答案有效,但如果输入枚举和/或模式足够大,则表现简直可怕。如果为作业选择更合适的集合,则可以显着提高性能::

public static IEnumerable<T> GetChunks<T>(this IEnumerable<T> source, IEnumerable<T> pattern)
    where T: IEquatable<T>
{
    var dictionary = pattern.ToDictionary(p => p, p => new Stack<T>());

    foreach (var item in source)
    {
        dictionary[item].Push(item);
    }

    var rest = source.Except(pattern);

    while (dictionary.Values.Any(q => q.Any()))
    {
        foreach (var p in pattern)
        {
            if (dictionary[p].Count  >0)
            {
                yield return dictionary[p].Pop();
            }
        }
    }

    foreach (var r in rest)
    {
        yield return r;
    }
}

这里的诀窍是建立一个廉价字典,以利用它提供的更快的查找。

我也冒昧地决定将所有不匹配的元素添加到&#34;命令&#34;结果。这可能不是你想要的,但问题在这方面没有说明。