C# 如何从另一个列表中排序具有匹配键的对象列表?

C# 如何从另一个列表中排序具有匹配键的对象列表?,c#,.net,.net-core,C#,.net,.net Core,我需要根据另一个对象列表(具有匹配的键)对现有对象列表进行排序,但两个列表可能包含也可能不包含相同的键和项目数。例如: struct Item { public string _id; public Item(string id) { _id = id; } } List<Item> totalItems = new List<Item>() { new Item("foo"), new Item("bar"), new Item("b

我需要根据另一个对象列表(具有匹配的键)对现有对象列表进行排序,但两个列表可能包含也可能不包含相同的键和项目数。例如:

struct Item 
{
    public string _id;
    public Item(string id) { _id = id; }
}

List<Item> totalItems = new List<Item>()
{
    new Item("foo"), new Item("bar"),
    new Item("baz"), new Item("monkey"),
    new Item("cat"), new Item("apple")
};

List<string> preferredSortOrder = new List<string>()
{
    "monkey",
    "cat",
    "zebra",
    "baz"
};
这是因为来自preferredSortOrder的排序顺序优先,所以monkey、cat和baz位于列表的第一位,因为它们存在于totalItems中。如果preferredSortOrder列表中的某些内容在totalItems中不存在,则应忽略它。totalItems中的所有剩余项都应该按字母顺序排列(如上面所示)

我已经好几年没有在linq中编码了,到目前为止我尝试的一切都没有成功

编辑:根据Calimero的回答,以下是解决方案:

totalItems = totalItems
.OrderBy(item => item._id)
.OrderBy(item => {
    var i = preferredSortOrder.IndexOf(item._id);
    return i == -1 ? totalItems.Count : i;
}).ToList();
使用引用列表的方法作为具有Linq的键选择器函数参数

totalItems.OrderBy(item => preferredSortOrder.IndexOf(item._id)).ToList();
编辑:这将把不在引用列表中的元素放在第一位(因为IndexOf将返回-1)。但是您可以很容易地返回一个大于这种情况下任何可能索引的值

totalItems.OrderBy(item => 
{ 
   var index = preferredSortOrder.IndexOf(item._id);
   return index == -1 ? totalItems.Count : index
}).ToList();
如果您有重复使用的情况,您可以将其作为扩展方法

编辑2:我没有注意到你的_id是私有的(你没有指定可访问性,这里是默认的可访问性)。您可能希望拥有一个将其用作支持字段的属性,或者将其公开

  • 向结构项添加第二个字符串字段,称之为“sortOrder”
  • 为“preferredSortOrder”创建一个类或结构,添加第二个字符串字段(“sortOrder”),该字段指示排序顺序。使用数字,因为它们将在alpha之前排序
  • 第一次通过“totalItems”,在“preferredSortOrder”上查找,复制sortOrder。如果找不到该项,请复制其字符串(例如“apple”)
  • 对sortOrder上的totalItems进行排序。普雷斯托
    您在expected
    totalItems
    preferredSortOrder
    中是否有重复项?如果是,那么预期输出是什么?您的
    \u id
    属性是否对外公开?totalItems中不会有重复项。可能是在preferredSortOrder中,但那只是一个json配置错误(我们知道这经常发生),我无法修改排序顺序列表。@u84six您不需要修改排序顺序列表。是的,我刚刚注意到了这一点。现在,我只是更新了我的问题,把它公之于众。表单不好,但这对这个问题并不重要。这一行在OrderBy中“return index=-1?totalItems.Count:index”做什么?我正在尝试按字母顺序对totalItems中的剩余项进行排序,如果在preferredSortOrderI中不存在键,我知道我可以使用循环进行排序,但这并没有那么酷。我不确定是否可以在不使用循环的情况下对剩余的项目进行排序。我解释了它的作用,它将剩余的元素放在末尾。如果要按字母顺序对其余元素进行排序,可以向计数中添加一个值。你也不知道你的字母顺序是否考虑了大小写,大小写无关紧要。
    totalItems.OrderBy(item => 
    { 
       var index = preferredSortOrder.IndexOf(item._id);
       return index == -1 ? totalItems.Count : index
    }).ToList();