【问题标题】:Sort One Array from Another array order?从另一个数组顺序排序一个数组?
【发布时间】:2011-07-06 17:32:49
【问题描述】:
var listOne = new string[] { "dog", "cat", "car", "apple"};
var listTwo = new string[] { "car", "apple"};

我需要按 listTwo 中的项目顺序(如果存在)对 listOne 进行排序。所以新列表将按此顺序排列; “汽车”、“苹果”、“狗”、“猫”

我想在 LINQ 中执行此操作并尝试过此操作;

var newList = from l1 in listOne
              join l2 in listTwo on l1 equals l2 in temp
              from nl temp.DefaultIfEmpty()
              select nl;

但它返回 null 很明显我的 Linq-Fu 很弱。任何建议表示赞赏。

【问题讨论】:

  • listOne 中是否可以存在重复项?如果是这样,它们应该被保留吗?

标签: c# arrays linq sorting


【解决方案1】:

您需要 listTwo 中 listOne 中的所有项目,然后是 listOne 中的其余项目吗?

var results = listTwo.Intersect(listOne).Union(listOne);
foreach (string r in results)
{
    Console.WriteLine(r);
}

【讨论】:

  • 为什么需要第二个除外?这是一个工会;它们不会出现两次。
  • 我已经更改为 Concat 一分钟,但你是对的。没有 except 的联合可能更优雅。 listTwo.Intersect(listOne).Union(listOne);
  • @Lasse 我最初的答案是联合而不是 Concat。标记是正确的。
  • 这可以进一步缩短为listTwo.Union(listOne)Per MSDN:“此方法从返回集中排除重复项。”
  • @Ahmad 如果 listTwo 包含“橙色”但 listOne 没有,您的解决方案会包含它,但我的不会。按照我的阅读方式,listTwo 只能用于对 listOne 的项目进行排序,因此不应包含橙色。
【解决方案2】:

好吧,让我重新表述一下您的排序要求:

  1. 首先,第一个列表中的所有项目,也存在于第二个列表中,并按照它们在第二个列表中出现的顺序返回它们,:第二个列表中的所有元素列表,如果它们出现在第一个列表中
  2. 然后,第一个列表中所有不在第二个列表中的项目,并按照它们在第一个列表中出现的顺序返回它们

这段代码可以解决问题:

void Main()
{
    var listOne = new string[] { "dog", "cat", "car", "apple"};
    var listTwo = new string[] { "car", "apple"};

    var elements1 =
        from element in listTwo
        where listOne.Contains(element)
        select element;
    var elements2 =
        from element in listOne
        where !listTwo.Contains(element)
        select element;

    elements1.Concat(elements2).Dump();
}

您也可以在不使用 LINQ 语法的情况下重写它以使其更短:

void Main()
{
    var listOne = new string[] { "dog", "cat", "car", "apple"};
    var listTwo = new string[] { "car", "apple"};

    var elements = listTwo.Where(e => listOne.Contains(e))
        .Concat(listOne.Where(e => !listTwo.Contains(e)));

    elements.Dump();
}

输出(通过LINQPad):

car 
apple 
dog 
cat 

【讨论】:

  • 好的解决方案,顺便说一句,有listOne {"A","A","B","C"}listTwo{"A","C"} IMO 应该产生{"A","A","C","B"} 而不是{"A","C","B"} 就像你的代码一样......不知道OP是否需要这个;)跨度>
  • 顺便说一句,IntersectExceptWhere..Contains 效率更高
猜你喜欢
  • 2013-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 2021-08-12
相关资源
最近更新 更多