【问题标题】:Merge and Update Two Lists in C#在 C# 中合并和更新两个列表
【发布时间】:2009-08-19 09:45:52
【问题描述】:

我有两个List<T> 对象:

例如:

清单 1:
ID,值,其中 Id 被填充,值为空,它包含从 1 到 10 的 ID。
1,""
2,""
...
10,""

清单 2:
ID、Value 和其他属性都用值填充,但这个列表是列表 1 的子集,就 ID 而言。 (例如只有 3 件)
2,67
4,90
5,98

我想要的是一个合并列表 1,但具有更新的值。有没有人有任何好的扩展方法可以做到这一点或任何优雅的代码来执行这个操作。最终名单应该是:

ID、值
1,""
2,67 //列表 2 中的值
3,""
4,90
5,98
6,""
...
10,""

【问题讨论】:

  • 你的 Value 是字符串还是整数?您似乎在列表 1 中显示字符串,而在列表 2 中显示整数。

标签: c# .net linq list generic-list


【解决方案1】:

使用 linq:list1=list2.Union(list1);

【讨论】:

  • 我用两个list<Student> 类型的列表尝试了你的代码,班级学生看起来像这样Student student = new Student(){Id=1, Name="foo"} 使用这种语法list1 = list2.ToList().Union(list1.ToList()).ToList(); 但它没有合并两个列表;它只是像UNION -see example 3 一样将它们粘在一起。你确定是merges the list with updated values
  • 我发现了这个关于如何remove duplicates while merging lists 的问题,它确认您的代码只有在类覆盖GetHashCode()Equals() 时才有效
【解决方案2】:

我可能会使用字典而不是列表:

    // sample data
    var original = new Dictionary<int, int?>();
    for (int i = 1; i <= 10; i++)
    {
        original.Add(i, null);
    }
    var updated = new Dictionary<int, int>();
    updated.Add(2, 67);
    updated.Add(4, 90);
    updated.Add(5, 98);
    updated.Add(11, 20); // add

    // merge
    foreach (var pair in updated)
    {
        original[pair.Key] = pair.Value;
    }

    // show results
    foreach (var pair in original.OrderBy(x => x.Key))
    {
        Console.WriteLine(pair.Key + ": " + pair.Value);
    }

如果你在谈论一个对象的属性,它会更棘手,但仍然可行。

【讨论】:

    【解决方案3】:

    这是 O(m*n) 但应该为任意列表完成这项工作

            foreach (var record in List1)
            {
                var other = List2.FirstOrDefault(x => x.Key == record.Key);
                if(other != null) record.Value = other.Value;
            }
    

    如果保证列表是有序的,那么它可以降低到 O(n),但代价是更多的代码。该算法将是

    Current items start as head of each list
    While items remain in both lists
      If the current item of list1 has lower key than list2  advance to next in list1
      else if the current item of list2 has lower key than list1  advance to next in list2
      else copy value from current list2 item into list1 item and advance both lists.
    

    【讨论】:

      【解决方案4】:

      如果两个列表都按 ID 排序,则可以使用经典合并算法的变体:

      int pos = 0;
      foreach (var e in list2) {
        pos = list1.FindIndex(pos, x => x.Id==e.Id);
        list1[pos].Value = e.Value;
      }
      

      请注意,这还要求list2 在 ID 方面是list1 的严格子集(即list1 确实包含list2所有 id)

      当然你也可以把它封装在一个扩展方法中

      public static void UpdateWith<T>(this List<T> list1, List<T> list2) 
      where T:SomeIdValueSupertype {
        int pos = 0;
        foreach (var e in list2) {
          pos = list1.FindIndex(pos, x => x.Id==e.Id);
          list1[pos].Value = e.Value;
        }
      }
      

      【讨论】:

        【解决方案5】:
         private void btnSearch_Click(object sender, EventArgs e)
        {
        String searchBy = cmbSearchBy.Text.ToString();
        String searchFor = txtSearchFor.Text.Trim();
        
        var List3 = (from row in JobTitleDB.jobList
                                 where (row.JID.ToString()+row.JobTitleName.ToString().ToLower()).Contains(searchFor.ToLower())
                                 select row).ToList();
        if (searchBy == "All")
                    {
                        dgJobTitles.DataSource = null;
                        //dgJobTitles.DataSource = List1;
                        //dgJobTitles.DataSource = List2;
                        //dgJobTitles.DataSource = List1.Concat(List2);
                        //dgJobTitles.DataSource = List1.Union(List2);
                        dgJobTitles.DataSource = List3;
                        //dgJobTitles.DataSource=List1.AddRange(List2);
                    }
        }
        

        【讨论】:

        • 请在这里提供一些解释。删除不必要的注释代码。
        【解决方案6】:
        Dictionary<int, string> List1 = new Dictionary<int, string>();
        List1.Add(1,"");
        List1.Add(2,"");
        List1.Add(3,"");
        List1.Add(4,"");
        List1.Add(5,"");
        List1.Add(6,"");
        
        Dictionary<int, string> List2 = new Dictionary<int, string>();
        List2.Add(2, "two");
        List2.Add(4, "four");
        List2.Add(6, "six");
        
        var Result = List1.Select(x => new KeyValuePair<int, string>(x.Key, List2.ContainsKey(x.Key) ? List2[x.Key] : x.Value)).ToList();
        

        【讨论】:

          猜你喜欢
          • 2014-08-30
          • 1970-01-01
          • 2021-10-06
          • 2015-11-25
          • 2020-09-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-04
          相关资源
          最近更新 更多