【问题标题】:conditional Updating a list using LINQ使用 LINQ 有条件地更新列表
【发布时间】:2013-11-12 13:26:27
【问题描述】:

我有一个清单

List<Myclass> li = new List<Myclass>();

Myclass 在哪里

class Myclass
{
public string name {get;set;}
public decimal age {get;set;}
}

li 中的项目看起来像

 i want to update `li` according to name but with `LINQ` like

li.where(w=> w.name = "di") = li.Where(w => w.name =="di").select(s => {s.age = 10;return s;}).Tolist();
li.where(w=> w.name = "marks") = li.Where(w => w.name =="marks").select(s => {s.age = 20;return s;}).Tolist();
li.where(w=> w.name = "grade") = li.Where(w => w.name =="grade").select(s => {s.age = 10;return s;}).Tolist();

想要这样的结果

我的代码出错了,请告诉我是怎么做的

【问题讨论】:

  • 在不误导人们认为 LINQ 是解决您的问题的适当解决方案的情况下,这个问题很难/很危险地回答。 LINQ 代表语言集成查询。它旨在将本机数据查询引入 .NET。简单地说:你正在做的是不是查询。 @wudzik 的回答显示了 LINQ 的用途:作为查询集合的工具。你应该问自己“我应该在这里使用什么工具”,而不是试图强迫 LINQ 成为那个工具。

标签: c# linq list


【解决方案1】:

更清洁的方法是使用 foreach

foreach(var item in li.Where(w => w.name =="di"))
{
   item.age=10;
}

【讨论】:

  • 使用 LINQ 还不行吗
  • @Co.Aden LINQ 用于查询不改变
【解决方案2】:

你需要:

li.Where(w=> w.name == "di").ToList().ForEach(i => i.age = 10);

程序代码:

namespace Test
{
    class Program
    {
        class Myclass
        {
            public string name { get; set; }
            public decimal age { get; set; }
        }

        static void Main(string[] args)
        {
            var list = new List<Myclass> { new Myclass{name = "di", age = 0}, new Myclass{name = "marks", age = 0}, new Myclass{name = "grade", age = 0}};
            list.Where(w=> w.name == "di").ToList().ForEach(i => i.age = 10);
            list.ForEach(i => Console.WriteLine(i.name + ":" + i.age));
        }
    }
}

输出:

 di:10
 marks:0
 grade:0

【讨论】:

  • 它将创建一个新列表来替换旧列表,顺便说一句,这里唯一的 LINQ 是 where
  • 一个新列表,是的 - 但包含相同的项目,将正确更新。然后丢弃这个新列表。
  • 它将被丢弃,但是,您将如何替换旧的列表值? li=yourstatement 将删除其他值
  • 另外,Linq 在这里仅用于循环集合,就像 wudzik 的回答一样。 i.age = 10 部分与 item.age = 10 部分没有区别。在这两种情况下,更新都不是用 Linq 完成的 :)
  • 我附上了我的示例程序。该列表按预期更新。
【解决方案3】:
        li.Where(w => w.name == "di" )
          .Select(s => { s.age = 10; return s; })
          .ToList();

【讨论】:

  • 您能否在回答中加入一些描述,而不是仅仅发布一段代码?
  • 别忘了我花了一个小时的返回语法
  • 这将过滤li,其中名称为di。使用li 的子集,它会将所有这些项目的age 属性设置为10。所以这个li 不包含列表中的所有原始项目。换句话说,如果 li 包含一个名为 == "Bob" 的项目,那么 li 将丢失该项目。
  • A lambda expression with a statement body cannot be converted to an expression tree
【解决方案4】:

试试这个:

li.ForEach(x => x.age = (x.name == "di") ?
                10 : (x.name == "marks") ?
                20 : (x.name == "grade") ?
                30 : 0 );

所有值都在一行代码中更新,您只需浏览一次列表。您还可以设置默认值。

【讨论】:

  • 非常整洁!这正是我想要的
【解决方案5】:

如果你真的想使用 linq,你可以这样做

li= (from tl in li
    select new Myclass
    {
        name = tl.name,
        age = (tl.name == "di" ? 10 : (tl.name == "marks" ? 20 : 30))

    }).ToList();

li = li.Select(ex => new MyClass { name = ex.name, age = (ex.name == "di" ? 10 : (ex.name == "marks" ? 20 : 30)) }).ToList();

这假设只有 3 种类型的 name。我会将该部分外部化为一个函数,以使其更易于管理。

【讨论】:

    【解决方案6】:

    尝试并行以获得更长的列表:

    Parallel.ForEach(li.Where(f => f.name == "di"), l => l.age = 10);
    

    【讨论】:

      【解决方案7】:

      怎么样

      (from k in myList
       where k.id > 35
       select k).ToList().ForEach(k => k.Name = "Banana");
      

      【讨论】:

        猜你喜欢
        • 2014-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-14
        • 1970-01-01
        • 1970-01-01
        • 2021-07-21
        • 1970-01-01
        相关资源
        最近更新 更多