【问题标题】:Your Favorite LINQ-to-Objects Queries [closed]您最喜欢的 LINQ-to-Objects 查询 [关闭]
【发布时间】:2009-02-04 08:33:37
【问题描述】:

使用 LINQ,可以更轻松地解决许多编程问题 - 并且只需要更少的代码行。

您编写过哪些现实世界中最好的 LINQ-to-Objects 查询?

(与 C# 2.0 / 命令式方法相比,最佳 = 简单和优雅)。

【问题讨论】:

  • 一个很好的问题,但我认为它应该被维基化。

标签: .net linq linq-to-objects sample


【解决方案1】:

过滤掉列表中的空项。

var nonnull = somelist.Where(a => a != null);

创建一个字典,其中键是属性的值,值是该属性在列表中出现的次数。

var countDictionary = somelist
    .GroupBy(a => a.SomeProperty)
    .ToDictionary(g => g.Key, g => g.Count());

【讨论】:

  • somelist.Where(a => a != null) 的效率比somelist.OfType<T>()低一点
【解决方案2】:

LINQ 只是在 C#/VB 中添加了一些函数式编程概念。因此,是的,大多数事情都会变得容易得多。 C# 2.0 实际上有一些这样的——例如,参见 List 方法。 (尽管 C# 2.0 中的匿名方法语法过于冗长。)

这是一个小例子:

static readonly string badChars = "!@#$%^&*()";
bool IsUserNameValid(string userName) {
  return userName.Intersect(badChars).Any();
}

【讨论】:

    【解决方案3】:

    示例 1

    返回包含本地网络中所有可用 SQL Server 实例名称的列表

    private List<string> GetServerNames()
    {
        return SqlDataSourceEnumerator.Instance.GetDataSources().Rows.
            Cast<DataRow>().
            Select
            (
                row => row["ServerName"].ToString() + 
                      (row["InstanceName"] != DBNull.Value ? "\\" + row["InstanceName"].ToString() : "") + 
                      (row["Version"] != DBNull.Value ? " (" + row["Version"].ToString().Substring(0, 3) + ")" : "")
            ).
            OrderBy(s => s).
            ToList();
    }
    

    示例 2

    为新文件生成未使用的名称

    private string NewName(string newNamePrefix, List<string> existingFileNames)
    {
        return newNamePrefix + 
            (existingFileNames.
                Select
                (
                    n =>
                    {
                        if (n.StartsWith(newNamePrefix))
                        {
                            int i;
                            if (int.TryParse(n.Replace(newNamePrefix, ""), out i))
                                return i;
                        }
    
                        return 0;
                    }
                ).
                OrderBy(i => i).
                Last() + 1
            );
    }
    

    【讨论】:

    • 第一个示例需要哪些参考资料?我已经在 LinqPad 中尝试过,但它缺少程序集参考。
    【解决方案4】:

    我有两个我喜欢的非常荒谬但优雅的例子

    public static IEnumerable<bool> Information(this byte x)
    {
        return Enumerable.Range(0, 8).Select(i => ((x >> i) & 1) == 1);
    }
    
    public static IEnumerable<bool> Information(this IEnumerable<byte> xs)
    {
        return xs.SelectMany(Information);
    }
    

    尽管这些被封装为查询运算符,因此您可以重复使用它们,例如用于二进制解析

    var n = bytes.Information().Skip(3).Take(16).ToInt();
    

    【讨论】:

    • 我明白了 - 这是一个 ToBits() 函数。不错。
    • 是的;我更喜欢信息这个名字,因为信息的最小单位是一点。虽然它应该是一个扩展属性,但我们还没有。
    【解决方案5】:

    如果您有一个分隔的Name=Value 字符串,例如"ID=2;Name=James;Age=32;",并且您想快速将其变成字典,您可以使用:

    var dict = value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
        .Select(str => str.Split('='))
        .ToDictionary(pair => pair[0], pair => pair[1]);
    

    【讨论】:

      【解决方案6】:

      如果您有一个列表(即List&lt;Palette&gt; palettes),其中包含包含另一个列表(即Palette.Colors)的对象,并且想要将所有这些子列表合并为一个:

      List<Color> allColors = palettes.SelectMany(p => p.Colors);
      

      【讨论】:

        【解决方案7】:

        我喜欢在移植代码时对文本使用 LINQ:

        例如:

        String.Join("\n", @"some VB6 code
            that I could refactor automatically
            if FindAndReplace were a bit more powerfully
            And I don't want to refactor by hand".Split('\n').Trim().Select(line =>
            {
                if(line.Contains("FindAndReplace") && !line.StartsWith("//"))
                {
                    return line.Split(" ").Last();
                }
                else
                {
                    return String.Join("_", line.Split(" ").Take(3));
                }
            });
        

        你明白了。 Linq 让我可以将 C# 的全部功能应用于文本转换。通常,当我想要以一种复杂的方式提取和操作一种语言的代码时,我会使用它,我将文本单独放在 LinqPad 中并在引号上执行“查找替换”,用双引号替换它们,然后我用@"..." 包围它并开始工作。我通常可以在 30 秒左右完成大量代码转换。

        【讨论】:

          【解决方案8】:

          我最喜欢的是以下 Linq 示例,用于从 Northwind 数据库中动态排序 SQL 表

          void Main()
          {
          
          // Demonstrates dynamic ordering
          
          var SortExpression = "Total"; // choose ProductName or Total
          var sortAscending = true; // choose true for ascending, false for descending
          
          // the query to sort
          var data = (from pd in Products
                              join od in OrderDetails on pd.ProductID equals od.ProductID into DetailsByProduct
                              select new { ProductName = pd.ProductName, Total = DetailsByProduct.Count()}).ToList();
          
          // the data source you can use for data binding                     
          var ds= (sortAscending) 
              ? data.OrderBy(x => x.GetType().GetProperty(SortExpression).GetValue(x, null))
              : data.OrderByDescending(x => x.GetType().GetProperty(SortExpression).GetValue(x, null));
          
          ds.Dump();
          }
          

          它允许您通过简单地在变量SortExpression 中指定一个字段和在变量sortAscending 中指定排序顺序来动态排序。

          通过使用.Take(x).Skip(y),您还可以轻松实现分页

          【讨论】:

            【解决方案9】:

            让我开始了,太棒了!

            var myList = from list in myObjectList select list
            

            【讨论】:

            • 对不起,我没明白。这个例子有什么特别之处?
            • @Matt 7 年前那是相当整洁的。
            • @Matt 因为它是一种非常简单但功能强大的快速迭代列表的方法。从那里,很容易添加 where 子句等以 really 获得一些很棒的结果。代码将干净且易于阅读。
            • @Pure.Krome/Filip Ekberg - 我同意,但是 var myList = myObjectList.AsQueryable(); 会做同样的事情,但会更短。
            • @Matt,不过那不是 LINQ。
            猜你喜欢
            • 1970-01-01
            • 2011-01-03
            • 2010-11-05
            • 1970-01-01
            • 1970-01-01
            • 2011-01-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多