7

我有两个List<T>对象:

例如:

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

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

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

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



4

6 回答 6

9

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

于 2010-08-20T15:09:09.053 回答
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.
于 2009-08-19T09:57:14.323 回答
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);
    }

如果您在谈论对象的属性,那会比较棘手,但仍然可行。

于 2009-08-19T10:02:05.250 回答
0

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

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

请注意,这也需要在 ID 方面list2是严格的子集list1(即list1真正包含的所有id list2

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

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;
  }
}
于 2009-08-19T10:19:28.473 回答
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);
            }
}
于 2011-02-19T08:22:26.810 回答
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();
于 2016-11-07T07:53:48.620 回答