Home > front end >  C# foreach not returning unique values in list comparison
C# foreach not returning unique values in list comparison

Time:12-26

I have 2 lists of objects to compare form a matching field and create a new list. The new list should contain objects from List2 and remove objects found in list1.

The code below is not returning unique objects but looping through 6 times - the number of objects in List1 adding each to the list.

List<ViewportWrapper> vpList = new(); // List1 - has count of 6
List<ViewWrapper> vList = new(); // List2 - has count of 25
List<ViewWrapper> vNoSheet = new(); // New list - has count of 120 - should be 19

foreach (var vpId in colViewports)
{
    var tempvpid = vpId.ViewportViewId;
    vpList.Add(vpId);
    foreach (var v in colViews)
    {
        var tempv = v.ViewId;
        if (v.ViewIsTemplate == false)
        {
            vList.Add(v);
        }
        if (tempv != tempvpid && v.ViewIsTemplate == false)
        {
            vNoSheet.Add(v);
        }
    }
}

the complete class is

public ObservableCollection<ViewWrapper> GetViews()
    {
        var colViewports = new FilteredElementCollector(Doc)
            .OfClass(typeof(Viewport))
            .ToElements()
            .Select(x => new ViewportWrapper((Viewport)x));

        var colViews = new FilteredElementCollector(Doc)
            .OfCategory(BuiltInCategory.OST_Views)
            .WhereElementIsNotElementType()
            .ToElements()
            .Select(x => new ViewWrapper((View)x));

        List<ViewportWrapper> vpList = new();
        List<ViewWrapper> vList = new();
        List<ViewWrapper> vNoSheet = vList.Distinct().ToList();

        foreach (var vpId in colViewports)
        {
            var tempvpid = vpId.ViewportViewId;
            vpList.Add(vpId);
            foreach (var v in colViews)
            {
                var tempv = v.ViewId;
                if (v.ViewIsTemplate == false)
                {
                    vList.Add(v);
                }
                if (tempv != tempvpid && v.ViewIsTemplate == false)
                {
                    vNoSheet.Add(v);
                }
            }
        }

        return new ObservableCollection<ViewWrapper>(vNoSheet);

how to return a list of unique objects?

Thanks for any help!

CodePudding user response:

Based on your code example I would use something like this:

foreach(var vpId in colViewports)
{
     vpList.Add(vpId);
}

foreach (var v in colViews)
{
    if(v.ViewIsTemplate)
        continue;
    vList.Add(v);
    var foundInListOne = colViewports.FirstOrDefault(i => i.ViewportViewId == v.ViewId); 
    if (foundInListOne == null)
        vNoSheet.Add(v); 
}

You only add the item to the new list if the ViewIsTemplate property is false, so there is no need for 2 ifs, just skip to the next item if it is true. Otherwise add the item to the vList and then check if any first list item with the ViewportViewId that equals the ViewId of the current second list item exists, if not then add it to the thrid list.

I hope this helps, your question is a bit confusing since you use different names for lists one and two in the code and in the definition.

In your example the items are filtered because due to the nested iteration, you should have 150 (6 * 25) items. But due to the nested iteration all other items except the matches get added.

  • Related