按另一个不完整的列表排序列表

Sort List by another, incomplete list

好吧,我可能想多了。 我尝试按另一个列表对列表进行排序。只要另一个 List 包含 List 的所有元素,它就可以正常工作。 如果另一个 List 不完整并且我想将剩余的元素保留在 List 的末尾,那将是一个好的方法?

这里有一个例子:

public class Column
{
    public int Id;
    public string Name;
    public string Something;
    //...
}

public class Columns : IEnumerable<Column>
{
    private List<Column> columnList = new List<Column>;

    public void SortByName(List<Column> sortedIncompleteList)
    {
            var sorted = from incomplete in sortedIncompleteList
                         join current in columnList
                         on incomplete.FieldName equals current.FieldName 
                         select current;
            columnList = sorted.ToList();
    }
    //...
}

也许我把它简单化了,但是如果你想排序为什么不使用OrderBy呢?您可以使用以下逻辑首先获取两个集合中的项目:

public void SortByName(List<Column> sortedIncompleteList)
{
    columnList = columnList
     .OrderByDescending(c => sortedIncompleteList.Any(c2 => c.FieldName == c2.FieldName))
     .ToList();
}

根据评论更新:"but not in the order they actually appear in sortedIncompleteList":

public void SortByName(List<Column> sortedIncompleteList)
{
    columnList = columnList
       .OrderBy(c => {
           int index = sortedIncompleteList.FindIndex(c2 => c.FieldName == c2.FieldName);
           if (index == -1) return int.MaxValue;
           return index;
       })
       .ToList();
}

我假设您列表中的元素是唯一的,因为 Column 有一个 Id 字段,因为我的解决方案将删除重复项。

public class Columns : IEnumerable<Column>
{
    private List<Column> columnList = new List<Column>;

    public void SortByName(List<Column> sortedIncompleteList)
    {
            columnList = sortedIncompleteList.Intersect(columnList)
                            .Concat(columnList.Except(sortedIncompleteList)).ToList();
    }
    //...
}

Intersect()Concat()Except() 将保留顺序...

你可以使用这样的东西:

var ids = sortedIncompleteList.Select(li => li.Id).ToList();

var ordered = from element in columnList
              let index = ids.IndexOf(element.Id)
              orderby index < 0 ? columnList.Count : index
              select element;