【问题标题】:C# List<> Arrange by another List value [duplicate]C# List<> 按另一个列表值排列[重复]
【发布时间】:2016-04-28 17:56:23
【问题描述】:

我有一个列表,我想按另一个序列列表排序。

List<string> Source = new List<string>() { "A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G" };
List<int> Sequence = new List<int>(){ 2, 1, 3, 5, 4, 6, 7 };

我怎样才能得到新的列表,这样我的结果就像

List<string> Output = new List<string>(){ "B" ,"A" ,"C" ,"E" ,"D" ,"F" ,"G" }; 

附:我可以使用下面的代码来得到结果。但是我想学习另一种方法。

    private List<string> ArrangeList(List<string> i_lsData, List<int> i_nSequence)
    {
        List<string> lv_lsTempList = new List<string>();

        foreach(int Temp in i_nSequence)
        {
            lv_lsTempList.Add(i_lsData[Temp]);
        }

        return lv_lsTempList;
    }

【问题讨论】:

  • 学习使用类而不是多个相关的集合。
  • private List&lt;string&gt; ArrangeList(List&lt;string&gt; i_lsData, List&lt;int&gt; i_nSequence) { return i_nSequence.Zip(i_lsData, (k, v) =&gt; new { k, v }).OrderBy(k =&gt; k.k).Select(k =&gt; k.v).ToList(); }
  • 序列为{ 2, 3, 1, 5, 4, 6, 7 }的结果是什么?
  • 看来这个问题可以用两种方式来解释。值“2”作为Sequence 的第一个元素是否意味着结果应该首先包含Source 列表中的第二个元素?或者这是否意味着Source 的第一个元素应该在结果列表中排在第二位?

标签: c# list


【解决方案1】:

您可以使用 LINQ 为您根据索引进行排序:

var list = Source.Select((item, index) => new { Item = item, Index = Sequence[index] })
                 .OrderBy(s => s.Index)
                 .Select(s => s.Item);

首先我使用Select 来获取Source 中项目的索引,并在Sequence 中找到对应的项目。然后我们对其进行排序并取回原始项目。

【讨论】:

    【解决方案2】:

    或使用 Zip:

    var ordered = Source
        .Zip(Sequence, (source, seq) => new { Item = source, Index = seq })
        .OrderBy(s => s.Index)
        .Select(s => s.Item);
    

    Zip 在同一位置逐项对两个可枚举项进行配对。 lambda 表达式可用于创建具有相同位置的两个项目的东西(在本例中为匿名方法)。

    与其他解决方案相比,它不会调用

    Sequence[index]
    

    对于源中的每个项目。而是将两个集合一起迭代。这对性能更好,并且允许在无法进行索引访问时执行相同操作(例如:使用两个 IEnumerables)。

    【讨论】:

      【解决方案3】:

      这是一个 LINQ 版本:

      var result =
          Source
          .Select((x,i) => new {Item = x, Index = i})
          .OrderBy(v => Sequence.IndexOf(v.Index + 1))
          .Select(v => v.Item)
          .ToList();
      

      【讨论】:

      • 为什么使用IndexOf作为订单?
      • 这是我尝试解决问题时的想法。有用。但现在我看到您有一个性能更好的解决方案。如果列表很小也没关系。
      • @PatrickHofman,实际上,我们正在解决两个不同的问题。
      • 是的,看起来是这样...... :)
      • @PatrickHofman,例如{ 2, 3, 1, 5, 4, 6, 7 } 的序列将使用我的答案或你的答案产生不同的结果。
      猜你喜欢
      • 2012-10-31
      • 2014-05-28
      • 1970-01-01
      • 2019-01-17
      • 2013-12-29
      • 2020-09-24
      • 2016-11-06
      • 2022-01-04
      • 1970-01-01
      相关资源
      最近更新 更多