Linq Conditional .Any() Select

本文关键字:Select Any Conditional Linq | 更新日期: 2023-09-27 18:27:47

如何对列值执行条件选择,其中我有返回值的首选项。如果我找不到最佳选择,我会选择下一个,如果有,然后如果没有,等等。现在看起来,总共需要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";
}

Linq Conditional .Any() Select

您可以使用string[]作为您的首选项:

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

EditEnumerable.Join是一种非常高效的哈希表方法,它只需要一个查询:

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

演示

我写了一个扩展方法,它有效地反映了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];
}

我在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");
}

这样的东西怎么样:

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";
}