2

如何对列值执行条件选择,我对返回哪个值有偏好。如果我找不到最佳选择,我会选择下一个,如果有的话,然后如果不是下一个,等等。现在看起来,总共需要 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

4 回答 4

7

您可以将 astring[]用于您的偏好:

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

编辑 Enumerable.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();

演示

于 2013-08-14T21:49:59.883 回答
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];
}
于 2013-08-14T22:20:47.853 回答
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");
}
于 2013-08-14T23:13:23.380 回答
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";
}
于 2013-08-14T21:50:16.823 回答