backtrack
backtrack

Reputation: 8144

remove duplicate based on position

I have two lists like below in C#.

List 1 = [{Item="A",position =1},{Item="B",position =2},{Item="A",position =3}]
List 2 = [{Item="AA",position =1},{Item="BB",position =2},{Item="AC",position =3}]

Now i want to remove duplicate values in the List 1 and that position should be removed in the List 2.

Example o/p

   List 1 = [{Item="A",position =1},{Item="B",position =2}]
    List 2 = [{Item="AA",position =1},{Item="BB",position =2}]

Can any one help me. Thanks.

Upvotes: 0

Views: 115

Answers (2)

xanatos
xanatos

Reputation: 111850

List<string> lst1 = new List<string> { "A", "B", "A" };
List<string> lst2 = new List<string> { "AA", "BB", "AC" };

HashSet<string> seen = new HashSet<string>();

for (int i = 0; i < lst1.Count; i++) {
    if (!seen.Add(lst1[i])) {
        lst1.RemoveAt(i);
        lst2.RemoveAt(i);
        i--;
    }
}

I used a HashSet to "save" the "already seen" elements of lst1 and then simply cycle the lst1 and remove the duplicate elements. HashSet.Add returns true if the HashSet doesn't already have an element, false if it already has it.

It isn't exactly clear what you want/what you have, but here there is the solution for another possible use case:

public class MyObject {
    public string Item;
    public int Position;
}

List<MyObject> lst1 = new List<MyObject> { 
    new MyObject { Item = "A", Position = 1 },
    new MyObject { Item = "B", Position = 2 },
    new MyObject { Item = "A", Position = 3 },
};

List<MyObject> lst2 = new List<MyObject> { 
    new MyObject { Item = "AA", Position = 1 },
    new MyObject { Item = "BB", Position = 2 },
    new MyObject { Item = "AC", Position = 3 },
};


HashSet<string> seen = new HashSet<string>();
HashSet<int> toBeDeleted = new HashSet<int>();

for (int i = 0; i < lst1.Count; i++) {
    if (!seen.Add(lst1[i].Item)) {
        toBeDeleted.Add(lst1[i].Position);
        lst1.RemoveAt(i);
        i--;
    }
}

if (toBeDeleted.Count > 0) {
    for (int i = 0; i < lst2.Count; i++) {
        if (toBeDeleted.Contains(lst2[i].Position)) {
            lst2.RemoveAt(i);
            i--;
        }
    }

    // or equivalent and shorter, without the for cycle
    //lst2.RemoveAll(x => toBeDeleted.Contains(x.Position));
}

In this case in a first pass on lst1 we remove the duplicate items (as seen in the first example) and "save" the Positions that need to be deleted in the HashSet<int> tobedeleted and then we do a second pass on lst2 to remove the elements that need deleting.

Upvotes: 1

111
111

Reputation: 1779

Much not clear what you want do, but I try with this:

var filteredList1 = list1.GroupBy(x => x.Item).Select(g => g.First()).ToList(); 
var removeElements = list2.Where(f => !filteredList1.Any(t => t.Position == f.Position)).ToList();  
removeElements.ForEach(x => list2.Remove(x));

Upvotes: 1

Related Questions