在C#中合并和更新两个列表

时间:2009-08-19 09:45:53

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

我有两个List<T>个对象:

例如:

列表1:
ID,填充Id的值,值为空,包含1到10的说明ID 1 “”
2 “”
...
10 “”

列表2:
ID,值和其他属性都填充了值,但此列表在ID方面是List 1的子集。 (例如只有3项)
2,67
4,90
5,98

我想要的是合并列表1,但更新的值。有没有人有任何好的扩展方法可以执行此操作或执行此操作的任何elegent代码。最终的清单应该是:

ID,值
1 “”
来自清单2的2,67 //值 3 “”
4,90
5,98
6 “”
...
10,“”

6 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分: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)。 algortihm将是

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.

答案 2 :(得分:3)

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

    // 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 :(得分:0)

如果您有两个按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确实包含<{>所有 ID {{1} }})

当然你也可以用扩展方法

包装它
list2

答案 4 :(得分:0)

 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);
            }
}

答案 5 :(得分:0)

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();