2012-11-09 54 views
3

阵列不同的λ的比较我有以下形状数据具有优先

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。例如,如果我选择了其他的TypeEnum,我还是希望它默认为默认值,如果它不能找到一个版本的类与“其他” TypeEnum

例如随着“其他”选择为ENUM类型,上面的数据会看起来像

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

我现在正在做的是从here

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

我希望鲜明弹出一个lambda比较数组中的任何x都会从该表达式中得到一个true。

我错了我认为不同的作品。如果我是,我应该用什么来代替?

回答

2

可以定义一个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); 
    } 
} 

UPDATE: 如果你只在您的首选或默认TypeEnum元素感兴趣,你可以过滤掉其余的首先。然后根据比较器对数组进行排序,即给予比默认更高的优先级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()); 

或者你可以用下面的版本,如果你不希望定义一个比较器类:

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()); 
+0

+1打我的一拳。我刚刚就是这个意思。 – TylerOhlsen

0

试试这个,使用DefaultIfEmpty("Default")

 var someArray = new List<TestClass> 
          { 
           new TestClass {Name = "Some Class", TypeEnum = "Default"}, 
           new TestClass {Name = "Some Class", TypeEnum = "Other"}, 
           new TestClass {Name = "Some Class 2", TypeEnum = "Default"}, 
           new TestClass {Name = "Some Class 2", TypeEnum = "Other"}, 
           new TestClass {Name = "Some Class 3", TypeEnum = "Default"} 
          }; 

     string myEnum = "Other"; 

     var result = someArray.GroupBy(t => t.Name). 
        Select(t => new TestClass 
         { 
          Name = t.Key, 
          TypeEnum = t.Select(s => s.TypeEnum).Where(p => p == myEnum).DefaultIfEmpty("Default").FirstOrDefault() 
         }); 
1

可以使用的GroupBy得到一个字典做这方面的工作。可能它也更简单。

List<Tuple<string, string>> lst = new List<Tuple<string, string>>(); 
lst.Add(new Tuple<string, string>("Some Class", "Default")); 
lst.Add(new Tuple<string, string>("Some Class", "Other")); 
lst.Add(new Tuple<string, string>("Some Class 2", "Default")); 
lst.Add(new Tuple<string, string>("Some Class 2", "Other")); 
lst.Add(new Tuple<string, string>("Some Class 3", "Default")); 

var dict = lst.GroupBy(g => g.Item1) 
       .ToDictionary(g => g.Key, k => k.Select(s => s.Item2) 
               .Where(p => p == "Other") 
               .DefaultIfEmpty("Default") 
               .First()); 

或者你的情况:

TypeEnum myEnum = "Other" 
var dict = lst.GroupBy(g => g.Name) 
    .ToDictionary(g => g.Key, k => k.Select(s => s.TypeEnum) 
           .Where(p => p == myEnum) 
           .DefaultIfEmpty("Default") 
           .First()); 
1

鲜明不工作,你所希望的方式和这里的原因,你可能永远无法得到它本身的工作。独特之处在于使用散列表来查找唯一值。它按顺序将每个项目添加到哈希表中,并省略添加与散列表中已存在的任何其他值相同的哈希值。

这意味着你的项目有关的事项的顺序,因为数组中的第一项获胜。我们可以通过在调用distinct之前修改列表的顺序来利用这个优势。修改@风的solution一点点,我们得到这个...

var result = someArray.OrderBy(key => key.TypeEnum, new TypeEnumComparer(myEnum)) 
    .Distinct(new LambdaEqualityComparer<SomeClass>((x, y) => x.Name == y.Name)); 

与修改比较器...

public class TypeEnumComparer : Comparer<TypeEnum> 
{ 
    private TypeEnum _preference; 

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

    public override int Compare(TypeEnum x, TypeEnum y) 
    { 
     if (x == y)    return 0; 
     if (x == _preference)  return -1; 
     if (y == _preference)  return 1; 
     if (x == TypeEnum.Default) return -1; 
     if (y == TypeEnum.Default) return 1; 

     return x.CompareTo(y); 
    } 
}