Reputation: 197
I'm having a problem not knowing how to use LINQ properly.
I have a List
of Dictionaries(string, object)
like this:
[0] -> "field1":1500, "field2":"dog", "field3":"blue"
[1] -> "field1":1700, "field2":"cat", "field3":"brown"
[2] -> "field1":1500, "field2":"horse", "field3":"white"
[3] -> "field1":1900, "field2":"cow", "field3":"black"
I need to get from this a List
of Dictionaries
with only the Dictionaries that have the "field1"
set to 1500
, so the output should be:
[0] -> "field1":1500, "field2":"dog", "field3":"blue"
[1] -> "field1":1500, "field2":"horse", "field3":"white"
I tried doing it like this but I'm sure I'm nowhere near the right answer.
List<Dictionary<string, object>> output = input.SelectMany(r => r).Where(r => (r.Key == "field1") && (r.Value == 1500)).ToList();
Please can you suggest me a solution for this?
Thank you very much.
Upvotes: 2
Views: 4110
Reputation: 37000
Whilst you could write your entire model as a collection of collections (of collections...) it´s merely a good idea as it´s impossible to understand and to maintain. You should definitly create your own classes, e.g.:
class MyClass
{
public int Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
}
Now you can create instances of those types and don´t have to mess up with object
. E.g.
var m = new MyType { Field1 = 1500, Field2 = "dog", Field3 = "blue" };
You can also put this into a collection:
var myList = new[] { m };
and even select elements from that list that satisfy your condition:
var result = myList.Where(x => x.Field1 == 1500);
Notice that Field1
is of type integer, so you get a compiler-error if you´re comparing the value with "MyValue"
for example. In your solution the dicitonaries values are of type object
, so you could store anything into Field1
, not just numbers.
Apart from all this you should also use some meaningful names for your members, e.g. Color
instead of Field2
and Animal
instead of Field2
.
Upvotes: 3
Reputation: 109567
This should work:
var result =
dicts.Where(
d => d.TryGetValue("field1", out object value) && value is int i && i == 1500
).ToList();
This picks out all the dictionaries in the list that have a field called field1
(via the d.TryGetValue()
) and where that value is also 1500
.
Note that because the dictionary contains object
and not int
, you need to check if the value is int
using is int i
.
Also note that this syntax uses the C# version 7 or later.
Upvotes: 3