基于优先条件获得单项的最有效方法

时间:2016-09-16 16:16:15

标签: c# linq

我有一个场景,每个组中有多个图像,需要根据字符串标准提取单个图像。

以下是现在的方式,它有效;但是,不确定这是否是最有效的方式,性能,尺寸,也可能是明智的练习

               foreach (var g in groups)
                {
                    SomeType file = null;

                    if (file == null)
                    {
                        file = g.Where(i =>
                                 i.URL.Contains("StringA")
                                 ).FirstOrDefault();
                    }
                    if (file == null)
                    {
                        file = g.Where(i =>
                                  i.URL.Contains("StringB")
                                  ).FirstOrDefault();
                    }
                    if (file == null)
                    {
                        file = g.Where(i =>
                                i.URL.Contains("StringC")
                                ).FirstOrDefault();
                    }
                    if (file == null)
                    {
                       // etc...
                    }
                    if (file == null)
                    {
                        file = g.FirstOrDefault();
                    }
                }

3 个答案:

答案 0 :(得分:2)

我担心你会发现这个答案有点无聊,但我会避免试图找到一些非常令人印象深刻但复杂的linq查询。我确信它可以做到,但不值得头疼。

将所有字符串粘贴在一个数组中,然后按优先顺序检查它们。除非你正在经历大量的物品,否则它将足够快。您没有执行数据库查询 - 您的foreach循环表明您的数据已经在内存中。

所以,我会失去大的if语句,并瞄准以下内容:

string [] my_list = new string [] {"StringA", "StringB", "StringC"};

foreach (var g in groups)
{
    foreach (string s in my_list)
    {
        file = g.Where(i => i.URL.Contains(s)).FirstOrDefault();
        if (file != null)
            break;
    }
    if (file == null)
    {
        file = g.FirstOrDefault();
    }
}

就像我说的那样,不是很令人兴奋,但在搜索中更改优先级和\或添加和删除字符串都很容易。

HTH,

亚当。

答案 1 :(得分:1)

string [] my_list = new string [] {"StringA", "StringB", "StringC"};
foreach (var g in groups)
{
   SomeType file = g.FirstOrDefault(i => my_list.Any(l=>i.Url.Contains(l))) 
                                   ?? g.FirstOrDefault();

}

答案 2 :(得分:0)

string[] filters = new[] { "StringA", "StringB", "StringC" };

foreach (var g in groups)
{
    SomeType file = filters.Select(s => g.FirstOrDefault(i => i.URL.Contains(s)))
                           .FirstOrDefault(m => m != null);
}

或者,如果您想要替换整个循环并实际将结果存储在某处:

var files = groups.Select(g => filters.Select(s => g.FirstOrDefault(i => i.URL.Contains(s)))
                                      .FirstOrDefault(m => m != null));

BTW:像

这样的表达式

file = g.Where(somePredicate).FirstOrDefault();

可以写成

file = g.FirstOrDefault(somePredicate);