1

I have a JSON that looks something like this:

"items": [
        "something": "",
        "something_2": "",
        "field_of_interest": {
          "blah": [
            {
              "placeholder": "1",
              "category": "random"
            },
            {
              "placeholder": "2",
              "category": "random",
              "field_to_null": {
                "something_here": "",
              }
            }
          ]
        }
      ]

I am trying to set the "field_to_null" field to null. These JSON fields are all encapsulated into objects and I have an expression that looks like this:

 Items.Select(x => x.FieldOfInterest)
       .Select(y => y.Blah
       .Select(z => z.FieldToNull).ToList().ForEach(a => a = null));

But I get an error on the second .Select. Error found here. Items is a List of Items objects and Blah is a List of FieldOfInterest objects. I am fairly new to C# and writing lambda linq expressions, so any help is appreciated.

Ruby
  • 413
  • 1
  • 4
  • 16
  • Firstly, Linq is really used for querying (hence the Q) and not for mutating objects. I personally hate the `ForEach` extension. Secondly, you have given us JSON but we have no idea what the C# classes are. What is `items`? – DavidG Nov 17 '21 at 12:41
  • @DavidG I agree, but I am using this code to write tests and would be convenient if I can set fields to null and run tests on that. `Items` is a List of `Items` objects and `Blah` is a List of `FieldOfInterest` objects. – Ruby Nov 17 '21 at 12:49

1 Answers1

1

Linq general philisophy is not to mutate things, which explains why ForEach is not a Linq extension method, but a method on some collection types, like List.

Usually try to avoid using unpure lambdas in Linq operators.

You can use Linq to do mutation nevertheless, via projection, using the Select operator, and passing it a lambda that will return the mutated argument. Here is the result.

Items
    .Select(i => 
    {
        i.FieldOfInterest.Blah = i.FieldOfInterest.Blah
            .Select(bi => 
            {
                bi.field_to_null = null;
                return bi;
            })
            .ToList() // Transform to the needed collection type
        return i;
    });

This is equivalent to:

foreach(var i in Items)
{
    foreach(var bi in i.field_of_interest.Blah)
    {
        bi.field_to_null = null;
    }
}

The Non-Linq approach is obvioulsly more readable.

Laurent Gabiot
  • 1,251
  • 9
  • 15