【问题标题】:How can I add and remove records from a collection with LINQ如何使用 LINQ 从集合中添加和删除记录
【发布时间】:2013-05-11 22:38:03
【问题描述】:

我有以下名为 City 的类,其中包含另一个名为 Detail 的类。

 public class City
    {
        public override string PartitionKey { get; set; }
        public override string RowKey { get; set; }
        public string Title { get; set; }

        public class Detail {
            public Detail() {
                Text = new HtmlText();
            }
            public HtmlText Text { get; set; }
        }

}

公共类 HtmlText {

public HtmlText()
{
    TextWithHtml = String.Empty;
}
[AllowHtml]
public string TextWithHtml { get; set; } 

}

在我的代码中,我使用以下内容创建详细信息列表。后来我填充了一些 细节但不是全部。

IList<City.Detail> Details = Enumerable.Range(1,6).Select(x => new City.Detail()).ToList();

我需要能够做两件事。有人可以告诉我最好的方法来做到这一点。希望使用 LINQ。

  • a) 从具有空文本字段的详细信息中删除任何 CityDetails?

  • b) 添加到详细信息以使其具有六个 City.Detail 记录(如果少于六个)?

【问题讨论】:

    标签: c# linq collections


    【解决方案1】:

    您的第一个问题可以通过使用这个“查询”来解决:

    Details = Details.Where(cityDetail=>cityDetail.Text != null && !string.IsNullOrEmpty(cityDetail.Text.TextWithHtml)).ToList();
    

    这将覆盖您的详细信息变量并使用新列表,仅包括非空项目。


    至于您的第二个问题 - 您并不清楚您想做什么,您需要向我们提供更多详细信息/解释

    编辑:
    IEnumerable(T) 表示只读集合,这意味着它不支持根据定义删除项目。当然你可以添加你自己的 RemoveWhere 扩展方法,但它本质上和我在这里做的一样

    【讨论】:

    • IEnumerable&lt;T&gt; 是只读的,但不是IList&lt;T&gt;,这是他正在使用的。这可能无关紧要,具体取决于对列表的引用是否已存储在其他地方。
    • 你是对的。我提到 IEnumerable 是因为他/她询问了 linq 查询,我认为通常应该强调 linq 是一种 QUERY 语言,因此主要用于只读场景
    • 我收到一条错误消息,提示无效表达式术语“=>”。请注意,Detail 是 City 类中的一个类。当我输入它时,我注意到 City.Detail 是蓝色的,但智能感知在 Detail 之后不建议任何内容,而不是等于和引用等于。你能告诉我LINQ是否有问题吗?
    • 我提到的细节是你粘贴在你的样本中的集合(IList 细节)。你可以粘贴你的确切代码吗?它似乎在这里对我有用,没有问题
    • 你好。现在可以了。抱歉,我已将您的代码更改为 LINQ 中的 City.Detail。现在我意识到你是对的。谢谢。
    【解决方案2】:

    @YavgenyP 很好地回答了您的第一个问题。对于第二个问题,我的建议如下:

    while (Details.Count < 6)
        Details.Add(new City.Detail());
    

    尝试使用 LINQ 执行此操作会更糟(长度、可读性、速度):

    if (Details.Count < 6)
        Enumerable.Range(1, 6 - Details.Count).Select(x =>
        {
            var d = new City.Detail();
            Details.Add(d);
            return d;
        }).ToArray();
    

    虽然我最喜欢他的解决方案,但这里有一些替代方法可以回答第一个问题:

    foreach (var toRemove in Details.Where(cityDetail => cityDetail.Text == null || string.IsNullOrEmpty(cityDetail.Text.TextWithHtml)))
        Details.Remove(toRemove);
    
    foreach (var toRemove in (from cityDetail in Details
                                  where cityDetail.Text == null || string.IsNullOrEmpty(cityDetail.Text.TextWithHtml)
                                  select cityDetail))
        Details.Remove(toRemove);
    
    (from cityDetail in Details
    where cityDetail.Text == null || string.IsNullOrEmpty(cityDetail.Text.TextWithHtml)
    select Details.Remove(cityDetail)).ToArray();
    

    【讨论】:

    • LINQ 出现错误。请注意,Detail 是 City 类中的一个类,因此它应为“City.Detail”。
    【解决方案3】:

    一)

    Details = 
       Details
       .Except(Details
           .Where(d => string.IsNullOrEmpty(d.Text.TextWithHtml)))
       .ToList();
    

    b)

     Details = 
        Details
          .Concat(
            Enumerable
            .Range(1, 6 - Details.Count())
            .Select(x => new City.Detail()))
          .ToList();
    

    【讨论】:

      猜你喜欢
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 2014-03-08
      相关资源
      最近更新 更多