Copy Few Items from One List to Another List of Same Type in C#

Copy few items from one list to another list of same type in c#

After a chat with OP I know OP wants to merge 2 lists with only partially defined fields into a complete list. I will call the starter lists list1 and list2 instead of oldList and newList

  • list 1 has id defined, name undefined, age undefined
  • list 2 has id undefined, name defined, age defined

So:

List<MyClass> newList =
list1.Zip(list2, (first, second) =>
new MyClass{id = first.id,name = second.name,age=second.age}).ToList();

However I truly recommend you use different classes. For example list1 could be a List<Integer> and list2 a List<MySmallerClass> containing only 2 fields.

(Also note in the original post you have really inverted newList with oldList.)

Copy content of one list to another list of a different type

The compiler can't guess how to convert from TemplateSection to Section. You must explicity do it yourself:

var ans = myTemplateSelections.Select(aTemplate => new Section {
SectionName = aTemplate.SectionName,
MyItems = aTemplate.MyTemplateItems.Select(ti => new MyItem {
ItemName = ti.ItemName,
ItemText = ti.ItemText //,
// ItemValue = ???
}).ToList();
};

Per a couple of comments, you can use Cast if you are willing to write your own conversion operators.

Change your template classes to include the conversion operators:

public class TemplateSection {
public string SectionName { get; set; }
public List<MyTemplateItem> MyTemplateItems { get; set; }

public static explicit operator Section(TemplateSection src) {
return new Section {
SectionName = src.SectionName,
MyItems = new List<MyItem>(src.MyTemplateItems.Cast<MyItem>())
};
}
}

public class MyTemplateItem {
public string ItemName { get; set; }
public string ItemText { get; set; }

public static explicit operator MyItem(MyTemplateItem src) {
return new MyItem {
ItemName = src.ItemName,
ItemText = src.ItemText
};
}
}

Then you can use Cast:

var sections = new List<Section>(myTemplateSections.Cast<Section>());

Copy specific items from a list of objects with a list of indexes corresponding to the id of the object

List.FindAll only provides the BikePart instances to the predicate, so you can't use it to select elements by index (unless the BikeParts id property always matches it's index).

If you want to avoid using an explicit loop, you can solve it using Linq like this:

return partsIndices.Select(index => allParts[index]).ToList();

Edit: I just re-read your comment and it seems to imply that the id property indeed always matches the index.

In that case List.FindAll can be used like this:

return allParts.FindAll(part => partsIndices.Contains(part.id));

However this is less efficient, as it will need to do a linear lookup (the Contains call) for every existing part (not just the selected ones).

It will also change the behavior of your existing code because it does not return duplicate entries if partsIndices contains the same index multiple times (as is the case with your example).

Update: The question edit clarified that the part "indices" are actually meant to represent the ids.

In that case a simple lookup by list index is not going to work.
This is your nested loop arrangement as a Linq expression (renamed partsIndices to partIds):

return partIds.Select(id => allParts.First(part => part.id == id)).ToList();

An alternative approach would be to first convert your list into a dictionary that maps each part id to the part instance and use that for the lookups.
This conversion would only need to be done once and could be reused for additional part queries.

Dictionary<int, BikePart> partsById = allParts.ToDictionary(part => part.id);
return partIds.Select(id => partsById[id]).ToList();

Copy list of items to another list

Since this is a reference type you are changing all. You need to create a copy of that instance:

public class MyClass 
{
private int id;

public int ID
{
get { return id; }
set { id = value; }
}

private string name;

public string Name
{
get { return name; }
set { name = value; }
}

public MyClass Copy()
{
return new MyClass
{
ID = this.ID,
Name = this.Name
};
}
}

Now you can create the second list in this way:

List<MyClass> list2 = new List<MyClass>(list1.Select(x => x.Copy()));

Of course you don't need that method. You could do that also on-the-fly in the LINQ query:

List<MyClass> list2 = new List<MyClass>(list1.Select(x => new MyClass { ID = x.ID, Name = x.Name }));

Another similar approach is a copy-constructor. A copy-constructor is used to initialize an instance by providing another instance of the same type:

public class MyClass
{
private int id;

public MyClass(MyClass instance)
{
this.id = instance.ID;
this.name = instance.Name;
}

public int ID
{
get { return id; }
set { id = value; }
}

private string name;

public string Name
{
get { return name; }
set { name = value; }
}
}

Now you could fill the list with copies in this way:

List<MyClass> list2 = new List<MyClass>(list1.Select(x => new MyClass(x)));

or with List.ConvertAll:

List<MyClass> list2 = list1.ConvertAll(x => new MyClass(x));

How do I copy items from list to list without foreach?

You could try this:

List<Int32> copy = new List<Int32>(original);

or if you're using C# 3 and .NET 3.5, with Linq, you can do this:

List<Int32> copy = original.ToList();

I see that this answer is still getting upvotes. Well, here's a secret for ya: the above answer is still using a foreach. Please don't upvote this any further.

Copying a portion of a list to a new list

Even though LINQ does make this easy and more general than just lists (using Skip and Take), List<T> has the GetRange method which makes it a breeze:

List<string> newList = oldList.GetRange(index, count);

(Where index is the index of the first element to copy, and count is how many items to copy.)

When you say "two dimensional list of strings" - do you mean an array? If so, do you mean a jagged array (string[][]) or a rectangular array (string[,])?



Related Topics



Leave a reply



Submit