C# 如何根据一个字段的给定序列对列表进行排序?

C# 如何根据一个字段的给定序列对列表进行排序?,c#,.net,linq,sorting,C#,.net,Linq,Sorting,我从数据库中读取了一个列表,类似于: var managers = _repo.Where(xxxx).ToList(); managers的数据以json格式显示 [ { "id":"b2071b2d-3d1a-4403-b044-0a59514c4431", "name":"Lucy", "mobile":"xxx" }, { "id":"639c108f-ec00-4fcd-814a-c3859930

我从数据库中读取了一个列表,类似于:

var managers = _repo.Where(xxxx).ToList();
managers
的数据以json格式显示

[
    {
        "id":"b2071b2d-3d1a-4403-b044-0a59514c4431",
        "name":"Lucy",
        "mobile":"xxx"
    },
    {
        "id":"639c108f-ec00-4fcd-814a-c3859930b1c1",
        "name":"Franck",
        "mobile":"xxx2"
    },
    {
        "id":"943b2ad4-8ef0-4cf7-824e-de3a7837a1cd",
        "name":"Jerry",
        "mobile":"xxx3"
    }
]

现在,我需要按给定的名称顺序对该列表重新排序,例如:

    var orderByName = _svc.GetManagerSortOrder(); // ["Jerry","Lucy","Franck"]
现在我正在使用
foreach
来实现这一点,代码太多了。还有更好的办法吗

以下是我当前的解决方案:

var orderByName = new List<string>() { "Franck", "Jerry" };
var sortedManagers = new List<Manager>();
foreach(string orderName in orderByName) // loop, and sort manager list based on a given name list
{
    var manager = managers.Where(a => a.name == orderName).FirstOrDefault();
    if (manager == null)
        continue;
    sortedManagers.Add(manager);
}

if(sortedManagers.Count != managers.Count) // if counts not equal, there is someone not on the name list, so these men need to be appended to the sortedManagers list
{
    var sortedManagersId = sortedManagers.Select(s => s.id);
    var managersNotInclude = managers.Where(a => !sortedManagersId.Contains(a.id)).ToList();
    sortedManagers = sortedManagers.Concat(managersNotInclude).ToList();
}
var orderByName=newlist(){“frank”,“Jerry”};
var sortedManagers=新列表();
foreach(orderByName中的字符串orderName)//循环,并基于给定名称列表对管理器列表进行排序
{
var manager=managers.Where(a=>a.name==orderName.FirstOrDefault();
if(manager==null)
继续;
分拣管理器。添加(管理器);
}
if(sortedManagers.Count!=managers.Count)//如果计数不相等,则有人不在名单上,因此需要将这些人添加到sortedManagers列表中
{
var sortedManagersId=sortedManagers.Select(s=>s.id);
var managersNotInclude=managers.Where(a=>!sortedManagersId.Contains(a.id)).ToList();
sortedManagers=sortedManagers.Concat(managersNotInclude.ToList();
}

不幸的是,如果不是为了处理源列表中不存在于目标列表中的名称,以下答案将对您有所帮助,因为
IndexOf()
为未发现的元素返回
-1

您需要做的是编写一个实现
ICompare
的客户
比较器。这可能看起来像这样:

class DependentComparer<T> : IComparer<T>
{
    // Backing field to contain the order dependent list
    List<T> lookUpTable;

    public DependentComparer(List<T> lookUpTable)
    {
        this.lookUpTable = lookUpTable;
    }

    public int Compare(T x, T y)
    {
        // Determine the index of the compared elements in the dependent list
        int xIndex = lookUpTable.IndexOf(x);
        int yIndex = lookUpTable.IndexOf(y);

        // If neither were in the dependent list, they are equal
        if ((xIndex == -1) && (yIndex == -1)) return 0;

        // If only the y was found, then y is greater than the x element
        if (xIndex == -1) return 1;
        // If only the x was found, then y is less than the x element
        if (yIndex == -1) return -1;

        // If both were found, then return the delta of their indicies
        return xIndex - yIndex;
    }
}
class DependentComparer:IComparer
{
//包含订单相关列表的支持字段
列表可查找;
公共从属比较程序(列表可查找)
{
this.lookUpTable=lookUpTable;
}
公共整数比较(TX,TY)
{
//确定相关列表中比较元素的索引
int xIndex=lookUpTable.IndexOf(x);
int yIndex=可查找的索引(y);
//如果两者都不在从属列表中,则它们相等
if((xIndex==-1)和&(yIndex==-1))返回0;
//如果只找到y,则y大于x元素
if(xIndex==-1)返回1;
//如果只找到了x,那么y小于x元素
如果(yIndex==-1)返回-1;
//如果两者都找到了,则返回其标记的增量
返回xIndex-yIndex;
}
}
这可以用作:

var orderByName = new List<string>() { "Frank", "Jerry" };
var managersNames = new List<string>() { "Jerry", "Frank", "Lucy" };

managersNames.Sort(new DependentComparer<string>(orderByName));
var orderByName=newlist(){“Frank”,“Jerry”};
var managersNames=新列表(){“Jerry”、“Frank”、“Lucy”};
Sort(新的DependentComparer(orderByName));
输出:
Frank,Jerry,Lucy


注意:此方法不会对
可查找表中未显示的元素执行排序操作。它们将按照它们在源中的顺序追加到结果的末尾。此外,给出的示例好像列表是
string
,而不是
manager
。转换很简单,但如果您需要编辑,请告诉我。

不幸的是,如果不是为了处理源列表中不存在于目标列表中的名称,以下答案将对您有所帮助,因为
IndexOf()
为未发现的元素返回
-1

您需要做的是编写一个实现
ICompare
的客户
比较器。这可能看起来像这样:

class DependentComparer<T> : IComparer<T>
{
    // Backing field to contain the order dependent list
    List<T> lookUpTable;

    public DependentComparer(List<T> lookUpTable)
    {
        this.lookUpTable = lookUpTable;
    }

    public int Compare(T x, T y)
    {
        // Determine the index of the compared elements in the dependent list
        int xIndex = lookUpTable.IndexOf(x);
        int yIndex = lookUpTable.IndexOf(y);

        // If neither were in the dependent list, they are equal
        if ((xIndex == -1) && (yIndex == -1)) return 0;

        // If only the y was found, then y is greater than the x element
        if (xIndex == -1) return 1;
        // If only the x was found, then y is less than the x element
        if (yIndex == -1) return -1;

        // If both were found, then return the delta of their indicies
        return xIndex - yIndex;
    }
}
class DependentComparer:IComparer
{
//包含订单相关列表的支持字段
列表可查找;
公共从属比较程序(列表可查找)
{
this.lookUpTable=lookUpTable;
}
公共整数比较(TX,TY)
{
//确定相关列表中比较元素的索引
int xIndex=lookUpTable.IndexOf(x);
int yIndex=可查找的索引(y);
//如果两者都不在从属列表中,则它们相等
if((xIndex==-1)和&(yIndex==-1))返回0;
//如果只找到y,则y大于x元素
if(xIndex==-1)返回1;
//如果只找到了x,那么y小于x元素
如果(yIndex==-1)返回-1;
//如果两者都找到了,则返回其标记的增量
返回xIndex-yIndex;
}
}
这可以用作:

var orderByName = new List<string>() { "Frank", "Jerry" };
var managersNames = new List<string>() { "Jerry", "Frank", "Lucy" };

managersNames.Sort(new DependentComparer<string>(orderByName));
var orderByName=newlist(){“Frank”,“Jerry”};
var managersNames=新列表(){“Jerry”、“Frank”、“Lucy”};
Sort(新的DependentComparer(orderByName));
输出:
Frank,Jerry,Lucy


注意:此方法不会对
可查找表中未显示的元素执行排序操作。它们将按照它们在源中的顺序追加到结果的末尾。此外,给出的示例好像列表是
string
,而不是
manager
。转换非常简单,但如果需要编辑,请告诉我。

因此,您有一系列管理者,其中每个管理者都有一个名称;你有一系列的名字,比如[“杰瑞”、“露西”、“弗兰克”]

你想对你的经理进行排序,首先让所有经理都被命名为“Jerry”,然后让所有经理都被命名为“Lucy”,等等。你想以不在你名字序列中的经理结束

考虑创建一个实现
IComparer
的对象:获得两个管理者,并决定谁应该首先执行。例如:一个经理叫“露西”,另一个经理叫“杰瑞”,所以“杰瑞”应该是第一个

用途如下:

IEnumerable<Manager> unorderedManagers = ...
IComparer<Manager> managerComparer = ...

IEnumerable<Manager> orderedManagers = unorderedManagers.OrderBy(managerComparer);
IEnumerable无序管理器=。。。
IComparer Manager Comparer=。。。
IEnumerable OrderedManager=unorderedManagers.OrderBy(managerComparer);
因此,让我们创建一个ManagerComparer类

class ManagerComparer : IComparer<Manager>
{
    public ManagerComparer(IEnumerable<string> names)
    {
    }

    public int Compare(Manager x, Manager y) {...}
    // TODO implement
}
类管理器比较者:IComparer
{
公共管理器比较程序(IEnumerable名称)
{
}
公共int比较(管理器x,管理器y){…}
//待办事项实施
}
如果您有两个管理器作为输入:x和y,yo
IEnumerable<Manager> unorderedManagers = ...
IEnumerable<string> orderByNames = new sting[] {"Jerry", "Lucy", ...}
IComparer<Manager> managerComparer = new ManagerComparer(orderByNames);

IEnumerable<Manager> orderedManagers = unorderedManagers.OrderBy(managerComparer);