c# - 排列具有偏好的不同 lambda 比较

标签 c# lambda comparison distinct

我有以下形状的数据

someArray = [{ Name: "Some Class", TypeEnum: "Default" },
 { Name: "Some Class", TypeEnum: "Other" },
 { Name: "Some Class 2", TypeEnum: "Default" },
 { Name: "Some Class 2", TypeEnum: "Other" },
 { Name: "Some Class 3", TypeEnum: "Default" },
 { Name: "Some Class 4", TypeEnum: "Not Other" }]

将它们中的每一个想象成 C# 中的对象

我需要的是该数组的不同版本的数组,并优先选择选定的 TypeEnum。例如,如果我选择了 other 的 TypeEnum,如果找不到带有“Other”TypeEnum 的该类的版本,我仍然希望它默认为 Default

例如选择“其他”作为类型枚举,上面的数据看起来像

 [{ Name: "Some Class", TypeEnum: "Other" },
 { Name: "Some Class 2", TypeEnum: "Other" },
 { Name: "Some Class 3", TypeEnum: "Default" }]

我现在正在做的是来自 here 的 lambda 比较

TypeEnum myEnum = "Other"
someArray.Distinct((x,y) => x.Name == y.Name && 
                   x.TypeEnum != myEnum && 
                   (y.TypeEnum == myEnum || y.TypeEnum == "Default"));

我希望 Distinct 从数组中弹出任何 x,该 x 是从该表达式获得的。

我认为 Distinct 的工作方式有误吗?如果是,我应该改用什么?

最佳答案

你可以定义一个Comparer<T>类来处理您的比较偏好,如下所示:

public class SomeClassComparer : Comparer<SomeClass>
{
    private TypeEnum _preference;

    public SomeClassComparer(TypeEnum preference)
        : base()
    {
        _preference = preference;
    }

    public override int Compare(SomeClass x, SomeClass y)
    {
        if (x.Name.Equals(y.Name))
        {
            return x.TypeEnum == y.TypeEnum ? 0
                : x.TypeEnum == _preference ? -1
                : y.TypeEnum == _preference ? 1
                : x.TypeEnum == TypeEnum.Default ? -1
                : y.TypeEnum == TypeEnum.Default ? 1
                : x.TypeEnum.CompareTo(y.TypeEnum);
        }
        else
            return x.Name.CompareTo(y.Name);
    }
}

更新: 如果您只对具有首选或默认值 TypeEnum 的元素感兴趣,您可以先过滤掉其余部分。然后根据 Comparer 对数组进行排序,即给出首选 TypeEnum优先级高于默认值。最后按名称对对象进行分组,并从每组中取出第一个:

var result = someArray.Where(x => x.TypeEnum == TypeEnum.Default || x.TypeEnum == myEnum)
                      .OrderBy(x => x, new SomeClassComparer(myEnum))
                      .GroupBy(x => x.Name)
                      .Select(x => x.First());

或者,如果您不想定义 Comparer 类,您可以使用以下版本:

Comparison<SomeClass> compareByTypeEnum = (x, y) =>
{
    if (x.Name.Equals(y.Name))
    {
        return x.TypeEnum == y.TypeEnum ? 0
            : x.TypeEnum == myEnum ? -1
            : y.TypeEnum == myEnum ? 1
            : x.TypeEnum == TypeEnum.Default ? -1
            : y.TypeEnum == TypeEnum.Default ? 1
            : x.TypeEnum.CompareTo(y.TypeEnum);
    }
    else
        return x.Name.CompareTo(y.Name);
};
Array.Sort(someArray, compareByTypeEnum);
var result = someArray.Where(x => x.TypeEnum == TypeEnum.Default || x.TypeEnum == TypeEnum.Other)
                      .GroupBy(x => x.Name)
                      .Select(x => x.First());

关于c# - 排列具有偏好的不同 lambda 比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13302705/

相关文章:

c# - 对于多个变量的循环性能 - C#

java - 如何将其包装为辅助函数?

python数字字符串比较

javascript - 将 Actionscript 转换为 Javascript

linux shell 查找、比较和删除文件

c# - 重构大泥球;不确定这里是否正确使用了静态。建议?

c# - 拥有具有 2 种数据类型的强类型数组的最简单方法?

c# - 锁 c#2 中抛出的异常

c# 将类作为参数传递

java - 如何对 Double 而不是 Integer 进行 Java lambda 求和?