【问题标题】:List Manipulation in C# using Linq使用 Linq 在 C# 中进行列表操作
【发布时间】:2008-12-12 04:47:30
【问题描述】:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace ConsoleApplication1
{

    public class Class1  
    {
       static void Main(string[] args)
       {
           List<Car> mylist = new List<Car>();
           Car car1;
           Car car2;
           Car car3;

           car1 = new Car()
           {
               make = "Honda",
               id = 1
           };
           car2 = new Car()
           {
               make = "toyota",
               id = 2
           };

           car3 = new Car()
           {
              make = "Honda",
              id = 3,
              color = "red"
           };

           mylist.Add(car1);
           mylist.Add(car2);
           **////mylist.Where(p => p.id == 1).SingleOrDefault() = car3;**
        }        
    }

    public class Car
    {
        public int id { get; set; }
        public string make { get; set; }
        public string color { get; set; }

    }
}

如何以最佳方式将 ID 1 的本田汽车替换为 ID 为 3 的本田汽车来更新列表。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    leppie 所说的一切 - 加:

    int index = mylist.FindIndex(p => p.id == 1);
    if(index<0) {
        mylist.Add(car3);
    } else {
        mylist[index] = car3;
    }
    

    这只是使用现有的 FindIndex 来定位 id 为 1 的汽车,然后替换或添加它。没有 LINQ;没有 SQL - 只有一个 lambda 和 List&lt;T&gt;

    【讨论】:

    • 感谢您的启发。
    • 如果我在index 有对汽车的引用SelectedCar,那么引用会被破坏还是SelectedCar 现在会指向car3 汽车?
    • 它是一个类,所以是同一辆车。结构不同,但
    • 想给这个加个通知:如果你不使用List对象开始,你必须先使用.ToList()或者类似的东西,FindIndex是一个List方法,不是Collection或者Array (或其他通用)方法。
    【解决方案2】:

    如果您想对多个元素进行更新...

    foreach (var f in mylist.FindAll(x => x.id == 1))  
    {    
        f.id = car3.id;  
        f.color = car3.color;  
        f.make = car3.make;  
    }  
    

    【讨论】:

      【解决方案3】:

      这不是 LINQ2SQL。

      另外,LINQ 不用于更新,仅用于查询对象。

      【讨论】:

        【解决方案4】:

        你可以这样使用:

        (from car in mylist
        where car.id == 1
        select car).Update(
        car => car.id = 3);
        

        我的参考是this website。或者下面是Update方法的代码

        public static void Update<T>(this IEnumerable<T> source, params Action<T>[] updates)
        {
            if (source == null)
                throw new ArgumentNullException("source");
        
            if (updates == null)
                throw new ArgumentNullException("updates");
        
            foreach (T item in source)
            {
                foreach (Action<T> update in updates)
                {
                    update(item);
                }
            }
        }
        

        【讨论】:

        • +1。这是一个很棒的链接。我不知道我更喜欢什么,生成的代码变得多么简洁,或者文章的彻底性。
        • -1 Update 与 ListForEach 相同。 ForEach wasn't included in IEnumerable 是有原因的。
        【解决方案5】:

        正如 Leppie 所说,LINQ 用于查询而不是更新。但是,这可以用来构建一个新列表:

        mylist = new List<Car>(from car in mylist select car.id == 1? car3 : car)
        

        如果你想使用 LINQ。当然,这是一个简短的代码,但比 Marc Gravell 的建议效率低,因为它有效地创建了一个新列表,而不是更新旧列表。

        【讨论】:

        • 一个很好的答案。我正在寻找一种通过从对象列表中选择特定字符串字段来返回字符串列表的简洁方法,并且您的方法非常有效。已投票。
        【解决方案6】:
        //Item class
        Class Item
        {
           public string Name { get; set; }
        }
        
        List < Item > myList = new List< Item >()
        
        //Add item to list
        Item item = new Item();
        item.Name = "Name";
        
        myList.Add(Item);
        
        //Find the item with the name prop
        
        Item item2 = myList.Find(x => x.Name == "Name");
        
        if(item2 != null)
           item.Name = "Changed";
        

        【讨论】:

          【解决方案7】:

          只有一个问题,为什么我必须为列表中看起来如此基本的东西编写更新函数?列表应该有标准的方法,例如 Add()、Delete()、Edit()、Insert()、Replace() ....Find()

          【讨论】:

          • 列表有all of those things。 IList 没有,因为他们想让接口易于为其他人实现。当然,现在我们有了扩展方法,这些东西could be pulled up to IList。另外:请在未来将 cmets 用于此类 cmets。
          【解决方案8】:
          List<AvailabilityIssue> ai = new List<AvailabilityIssue>();
          
          ai.AddRange(
              (from a in db.CrewLicences
                  where
                      a.ValidationDate <= ((UniversalTime)todayDate.AddDays(30)).Time &&
                      a.ValidationDate >= ((UniversalTime)todayDate.AddDays(15)).Time
                  select new AvailabilityIssue()
                  {
                      crewMemberId = a.CrewMemberId,
                      expirationDays = 30,
                      Name = a.LicenceType.Name,
                      expirationDate = new UniversalTime(a.ValidationDate).ToString("yyyy-MM-dd"),
                      documentType = Controllers.rpmdataController.DocumentType.Licence
                  }).ToList());
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-11-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多