Merge Two (Or More) Lists into One, in C# .Net

Merge two (or more) lists into one, in C# .NET

You can use the LINQ Concat and ToList methods:

var allProducts = productCollection1.Concat(productCollection2)
.Concat(productCollection3)
.ToList();

Note that there are more efficient ways to do this - the above will basically loop through all the entries, creating a dynamically sized buffer. As you can predict the size to start with, you don't need this dynamic sizing... so you could use:

var allProducts = new List<Product>(productCollection1.Count +
productCollection2.Count +
productCollection3.Count);
allProducts.AddRange(productCollection1);
allProducts.AddRange(productCollection2);
allProducts.AddRange(productCollection3);

(AddRange is special-cased for ICollection<T> for efficiency.)

I wouldn't take this approach unless you really have to though.

Joining two lists together

You could try:

List<string> a = new List<string>();
List<string> b = new List<string>();

a.AddRange(b);

MSDN page for AddRange

This preserves the order of the lists, but it doesn't remove any duplicates which Union would do.

This does change list a. If you wanted to preserve the original lists then you should use Concat (as pointed out in the other answers):

var newList = a.Concat(b);

This returns an IEnumerable as long as a is not null.

C# Linq merge multiple lists?

Maybe you just need SelectMany?

var results = AnArrayOfThings.SelectMany(x => Function(x));

Or in query syntax:

var results = from thing in AnArrayOfThings
from thingInAList in Function(thing)
select thingInAList;

Combine two lists into one based on property

There are many approaches depending on what is the priority, ex. Union + Lookup:

//this will create a key value pairs: id -> matching instances
var idMap = list1.Union(list2).ToLookup(myClass => myClass.ID);
//now just select for each ID the instance you want, ex. with some value
var mergedInstances = idMap.Select(row =>
row.FirstOrDefault(myClass => myClass.ExtId.HasValue) ?? row.First());

The benefit of above is that it will work with whatever amount of whatever lists even if they contain many duplicated isntances and then you can easily modify the conditions of merging

A small improvement would be to extract a method to merge instances:

MyClass MergeInstances(IEnumerable<MyClass> instances){
return instances.FirstOrDefault(myClass => myClass.ExtId.HasValue)
?? instances.First(); //or whatever else you imagine
}

and now just use it in the code above

 var mergedInstances = idMap.Select(MergeInstances);

Clean, flexible, simple, no additional conditions. Performance wise not perfect, but who cares.

Edit: since performance is the priority, some more options

  1. Do a lookup like above but only for the smaller list. Then iterate through the bigger and do the needed changes O(m log m) + O(n). m - smaller list size, n- bigger list size - should be fastest.

  2. Order both lists by elements ids. Create a for loop, that iterates through both of them keeping current index to the element with same id for both lists. Move index to the next smallest id found in both list, if one has it only, move only this on. O(n log n) + O(m log m) + O(n);

Combining contents of 2 lists in C#

You could use a for-loop and access the lists via index:

for(int i = 0; i < Math.Min(firstNames.Length, lastNames.Length); i++)
{
Console.WriteLine(firstNames[i] + lastNames[i]);
}

better would it be to store the two related information in a common class, for example Avenger with properties FirstName and LastName.

Another way to link two related lists is LINQ's Zip:

var zippedAvengers = firstNames.Zip(lastNames, (f,l) => f + " " + l);
foreach(string name in zippedAvengers)
Console.WriteLine(name);

Merge multiple ObjectList into one

If you need to get a sum of prices for concatenated List<Item>, you should use GroupBy method to group the items by Id and then Sum of prices for every group

var combined = food.Concat(drinks).Concat(magazines)
.GroupBy(i => i.Id, i => i.Price, (i, prices) => new Item { Id = i, Price = prices.Sum() })
.OrderBy(i => i.Id).ToList();

You can also add OrderBy to sort the results by Id property, if it's important

Merge two List object into one List in Linq

Use Concat and OrderBy

var result = list1.Concat(list2).OrderBy(x => x.Elevation).ToList();

If you want to remove duplicates and get an unique set of elements you can also use Union method:

var result = list1.Union(list2).OrderBy(x => x.Elevation).ToList();

In order to make it work properly you need to overide Equals and GetHashCode methods in your class.

How to merge multiple list by id and get specific data?

I think I'd mostly skip LINQ for this

class Thing{
public string Name {get;set;}
public int Count {get;set;}
public long LastTimestamp {get;set;}
}

...

var ids = new Dictionary<int, string>();
var result = new Dictionary<string, Thing>();
foreach(var g in groupNames) {
ids[g.Id] = g.Name;
result[g.Name] = new Whatever { Name = n };
}

foreach(var c in counts)
result[ids[c.Id]].Count++;

foreach(var l in lastTime){
var t = result[ids[l.Id]];
if(t.LastTimeStamp < l.Timestamp) t.LastTimeStamp = l.TimeStamp;
}

We start off making two dictionaries (you could ToDictionary this).. If groupNames is already a dictionary that maps id:name then you can skip making the ids dictionary and just use groupNames directly. This gives us fast lookup from ID to Name, but we actually want to colelct results into a name:something mapping, so we make one of those too. doing result[name] = thing always succeeds, even if we've seen name before. We could skip on some object creation with a ContainsKey check here if you want

Then all we need to do is enumerate our other N collections, building the result. The result we want is accessed from result[ids[some_id_value_here]] and it always exists if groupnames id space is complete (we will never have an id in the counts that we do not have in groupNames)

For counts, we don't care for any of the other data; just the presence of the id is enough to increment the count

For dates, it's a simple max algorithm of "if known max is less than new max make known max = new max". If you know your dates list is sorted ascending you can skip that if too..



Related Topics



Leave a reply



Submit