0

What would be the best approach to remove a value from a list where the property Id is contained in another list.

I tried this but is not quote working the way as expected.

internal static List<DashboardData> CloseWhereOpen(List<DashboardData> rawData, 
                                                   List<DashboardData> activitiesOpen)
{
    var index = 0; 

    foreach (var val in rawData)
    {
        if (activitiesOpen.Select(ao=>ao.CanvasId == val.CanvasId).Count() > 0)          {
            rawData.ToList().RemoveAt(index);
        }

        index++;
    }

    return rawData;
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Arianule
  • 8,811
  • 45
  • 116
  • 174
  • what did you expect? – DarkSquirrel42 Apr 06 '18 at 13:22
  • 1
    `rawData.ToList().RemoveAt(index);` will create a copy of `rawData`, remove item from that copy, then throw it away. Just read one of the hundreds of questions asking how to remove items from a list while enumerating. For example: https://stackoverflow.com/q/1582285/5311735 – Evk Apr 06 '18 at 13:24
  • `foreach (var val in rawData.Reverse().ToList())` then later `rawData.RemoveAt(index);` – mjwills Apr 06 '18 at 13:25

4 Answers4

3

I'm not sure if i understood your question correctly, but this should do the trick:

foreach (var val in activitiesOpen)
{
    rawData.RemoveAll(x => x.CanvasId == val.CanvasId);
}

Example lists (with integers for simplification):
(before)
activitiesOpen = { 1, 3 }
rawData = { 1, 2, 3, 4, 5 }

(after)
rawData = { 2, 4, 5 }

TomVA
  • 48
  • 3
2

You can get the canvasIds that need to be deleted and filter them out of the rawData list, then remove the whole range. i.e.

var canvasIds = activitiesOpen.Select(x => x.CanvasId).ToList();
var rawDataItemsToDelete = rawData.Where(x => canvasIds.Contains(x.CanvasId)).ToList();

rawData.RemoveRange(rawDataItemsToDelete);
Ahmad Ibrahim
  • 1,915
  • 2
  • 15
  • 32
1

You are removing from a newly created List:

       //new list     //remove it
rawData.ToList().RemoveAt(index);

A quick fix could be:

rawData = rawData.ToList().RemoveAt(index);

But then you are changing your collection. So, a better way is to use an inverted for loop:

internal static List<DashboardData> CloseWhereOpen(List<DashboardData> rawData, 
                                               List<DashboardData> activitiesOpen)
{
    var index = 0; 

    for (var i = rawData.Length -1; i >= 0; i--)
    {
        if (activitiesOpen.Select(ao=>ao.CanvasId == rawData[i].CanvasId).Count() > 0)      
        {
            rawData.RemoveAt(index);
        }
    }

    return rawData;
}

Or, just use one of the mentioned RemoveAll, RemoveRange methods ;-)

Stefan
  • 17,448
  • 11
  • 60
  • 79
1

ToList creates a new list, you want to remove from the existing.

I'd suggest this LINQ query:

rawData = rawData
    .Where(d => !activitiesOpen.Any(ao => ao.CanvasId == d.CanvasId))
    .ToList();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939