简体   繁体   中英

Remove elements from two lists based on another list

I have three lists. List1 contains some strings. List2 contains some numbers (uint in my case, although that's not very important) and it always has the exact same number of elements as the first one. List3 always has less elements and it also has some strings. Take notice that List1 contains all the elements that List3 has (as well as more strings).

What I want to do is to remove all elements from List1 that are included in List3 . However, I also want to remove elements from List2 in this way: If (for example), the 5th element of List1 has to be removed, then the 5th element from List2 has to removed. If the 12th element of List1 has to removed, then the 12th element from List2 has to be removed and so on.

I can remove the elements from List1 with this code: List1.RemoveAll(x => List3.Contains(x)) . However, I'm not very familiar with the RemoveAll method and I'm not sure how to remove the elements that I want from List2 in the way that I described.

Any ideas?

You can loop backward over the list, because then you can remove the elements from the end of the list, example:

for (var i = list1.Count - 1; i >= 0; i--)
{
    if (list3.Contains(list1[i]))
    {
        list1.RemoveAt(i);
        list2.RemoveAt(i);
    }
}

As suggested, a simple loop and index finder:

 list3.ForEach(x =>
   {  
      var index = list1.FindIndex(list3.Contains);
      list2.RemoveAt(index);
      list1.RemoveAt(index);
   }

But if first list contains duplicates:

 var query = list1.Where(list3.Contains).Select((value, index) => new {index}).ToList();
     query.ForEach(x =>
        {
           list2.RemoveAt(x.index);
           list1.RemoveAt(x.index);
        });

Maybe List1 and List2 could be combined into a Dictionary<string, int> if they are meant to be related? Then removing the data from List1 and List2 would amount to just deleting a KeyValuePair . But of course, List1 must not have any duplicates, otherwise the dictionary will have duplicate keys.

If a Dictionary would make sense semantically (with List1 containing the keys and List2 containing the corresponding values), here's an implementation:

Dictionary<string, uint> dictionary = List1.ToDictionary(key => key, key => List2[List1.IndexOf(key)];
Dictionary<string, uint> result = dictionary.Where(keyValuePair => !List3.Contains(keyValuePair.Key));

A similar implementation can be used if List2 should contain the keys and List1 should contain the values:

Dictionary<uint, string> dictionary = List2.ToDictionary(key => key, key => List1[List2.IndexOf(key)];
Dictionary<uint, string> result = dictionary.Where(keyValuePair => !List3.Contains(keyValuePair.Value));

Having List1 and List2 be so strongly connected (both lists have same number of elements; if an element is deleted from List1 , then the corresponding element should be deleted from List2 ) suggests that a Dictionary may be appropriate. (But it's just a suggestion. If a Dictionary doesn't work, I would use Dzienny's simple and effective loop-based solution.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM