Linq Conditional .Any()选择

时间:2013-08-14 21:45:13

标签: c# linq

如何对列值执行条件选择,其中我优先选择返回值。如果我找不到最佳选择,我会选择下一个,如果可用,然后如果不是下一个,等等。现在看起来,它将需要3个总查询。有没有办法进一步简化这个?

var myResult = string.Empty;

if (myTable.Where(x => x.ColumnValue == "Three").Any())
{
    myResult = "Three"; // Can also be some list.First().Select(x => x.ColumnValue) if that makes it easier;
}
else if (myTable.Where(x => x.ColumnValue == "One").Any())
{
    myResult = "One";
}
else if (myTable.Where(x => x.ColumnValue == "Two").Any())
{
    myResult = "Two";
}
else
{
    myResult = "Four";
}

4 个答案:

答案 0 :(得分:7)

您可以根据自己的喜好使用string[]

string[] prefs = new[]{ "One", "Two", "Three" };
string myResult = prefs.FirstOrDefault(p => myTable.Any(x => x.ColumnValue == p));
if(myResult == null) myResult = "Four";

修改 Enumerable.Join是一个very efficient哈希表方法,它只需要一个查询:

string myResult = prefs.Select((pref, index) => new { pref, index })
    .Join(myTable, xPref => xPref.pref, x => x.ColumnValue, (xPref, x) => new { xPref, x })
    .OrderBy(x => x.xPref.index)
    .Select(x => x.x.ColumnValue)
    .DefaultIfEmpty("Four")
    .First();

Demo

答案 1 :(得分:2)

我写了一个扩展方法,有效地反映了Tim Schmelter的答案(当他发布他的更新时测试了这个。: - ()

public static T PreferredFirst<T>(this IEnumerable<T> data, IEnumerable<T> queryValues, T whenNone)
{
    var matched = from d in data
                  join v in queryValues.Select((value,idx) => new {value, idx}) on d equals v.value
                  orderby v.idx
                  select new { d, v.idx };

    var found = matched.FirstOrDefault();

    return found != null ? found.d : whenNone;
}

// usage:
myResult = myTable.Select(x => x.ColumnValue)
                  .PreferredFirst(new [] {"Three", "One", "Two"}, "Four");

我写过一篇会早点退出的内容:

public static T PreferredFirst<T>(this IEnumerable<T> data, IList<T> orderBy, T whenNone)
{
    // probably should consider a copy of orderBy if it can vary during runtime
    var minIndex = int.MaxValue;

    foreach(var d in data)
    {
         var idx = orderBy.IndexOf(d);

         if (idx == 0) return d;  // best case; quit now

         if (idx > 0 && idx < minIndex) minIndex = idx;
    }

    // return the best found or "whenNone"
    return minIndex == int.MaxValue ? whenNone : orderBy[minIndex];
}

答案 2 :(得分:2)

我在SQL中使用加权方法,我为每个条件值分配权重。然后通过根据您的订购方案找到最高或最低重量来找到解决方案。

下面是等效的LINQ查询。请注意,在此示例中,我指定较低权重的优先级较高:

void Main()
{
    // Assume below list is your dataset 
    var myList =new List<dynamic>(new []{
    new {ColumnKey=1, ColumnValue  ="Two"},
    new {ColumnKey=2, ColumnValue  ="Nine"},
    new {ColumnKey=3, ColumnValue  ="One"},
    new {ColumnKey=4, ColumnValue  ="Eight"}});

    var result = myList.Select(p => new 
                            {
                                ColVal =    p.ColumnValue,
                                OrderKey =  p.ColumnValue == "Three" ? 1 : 
                                            p.ColumnValue == "One"   ? 2 : 
                                            p.ColumnValue == "Two"   ? 3 : 4
                             }).Where(i=> i.OrderKey != 4)
                             .OrderBy(i=>i.OrderKey)
                             .Select(i=> i.ColVal)
                             .FirstOrDefault();

    Console.WriteLine(result ?? "Four");
}

答案 3 :(得分:0)

这样的事情怎么样:

var results = myTable.GroupBy(x => x.ColumnValue).ToList();

if (results.Contains("Three")) {
    myResult = "Three"; 
} else if (results.Contains("One")) {
    myResult = "One";
} else if (results.Contains("Two")) {
    myResult = "Two";
} else {
    myResult = "Four";
}