对不同分支标准的操作LINQ

时间:2017-06-19 13:28:28

标签: c# .net linq

我想知道,有没有一种有效的方法可以使用LINQ在集合中实现分支逻辑,而不必多次迭代集合。

例如

    foreach (string file in Files){

      if (file== "file1"){
        \\do something
      }
      else if (file== "file2")
        \\do something
      }
      else if (file== "file3")
        \\do something
      }
    }

我找到了一个使用查找的解决方案,但仅适用于if-else情况

var group = Files.ToLookup(f => f=="file1");

var file1Group= group[true].ToList();

提前致谢。

2 个答案:

答案 0 :(得分:0)

这有帮助吗?基本上,您投影一个新的匿名类型,其中包含您希望按顺序排序,按分组依据或其他任何内容的额外属性。

using System;
using System.Linq;

namespace Test
{
    public class Program
    {
        static void Main(string[] args)
        {
            var Files = new string[] { "file1", "file2" };

            var withMetaData = Files.Select(z =>
                new { file = z, IsFile1 = z == "file1", IsFile2 = z == "file2"});

            // You can now OrderBy or GroupBy or whatever you fancy here

            foreach (var fileWithMetaData in withMetaData)
            {
                Console.WriteLine(fileWithMetaData);
            }

            Console.ReadLine();
        }
    }
}

答案 1 :(得分:0)

如果我有大量重复出现的动作,这些动作是在循环之前定义的并且必须是可重用的(否则if ...就像你已经拥有的那样可能更可取),我倾向于引用引用在字典(或其他集合)中的那些动作。对于这个特定的例子(文件),只有使用相同的文件名处理多个文件夹,或者从子字符串中获取'file x '部分才有意义,但这个概念可以应用于任何重复发生的分支逻辑。

下面的示例使用lambdas,但可以使用具有相同签名的任何现有方法

var actions = new Dictionary<string,Action>{
    {"file1", () => Console.WriteLine("abc")},
    {"file2", () => {var foo ="def"; Console.WriteLine(foo);}},
};

//example call, only to show usage
foreach(var file in new[]{"file1","file1","file2","file1"})
    actions[file](); //nb, for the example no check was added. For real use 'TryGetValue' can be used

当然,这是假设必须对每个文件执行操作,否则可以使用group by。

由于对每个文件使用了一个操作,因此该示例本身没有多大意义,因为没有针对单个文件的特定操作。因此,努力创造一个更明智的例子:

var actions = new Dictionary<string,Action<string>>{
    {"file1", f => Console.WriteLine("abc: {0}", f)},
    {"file2", f => {var foo ="def"; Console.WriteLine(foo);}},
};

foreach(var file in new[]{@"c:\temp\file1",@"c:\someotherfolder\file1",@"c:\temp\file2",@"c:\abc\file1"})
    actions[Path.GetFileNameWithoutExtension(file)](file); //nb, for the example no check was added. For real use 'TryGetValue' can be used