Roman Cerny
Roman Cerny

Reputation: 97

Linq Query Dictionary where value not in List

I have a Dictionary and another List. What I am trying to achieve is a LINQ query to get all items out of the dictionary where any values from said dictionary are not in the List<string>. I found this post to be helpful, Linq Query Dictionary where value in List. And was able to write the following LINQ expression.

What I have so far: Data is the dictionary and PersonList is the list of strings.

var Persons = Data.Where(kvp => !PersonList.Contains(kvp.Key))
                  .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

However, my results never actually return anything.

Update:

Dictionary<string, string> Data = new Dictionary<string, string>
{
    { "John", "aaa" },
    { "Tom", "bbb" },
    { "David", "ccc" }
};

List<string> PersonList = new List<string>
{
    "Tom",
    "Peter"
};

var Persons = Data.Where(kvp => !PersonList.Contains(kvp.Key))
                  .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

Upvotes: 1

Views: 2443

Answers (4)

user5877586
user5877586

Reputation:

You can try following code snippet

var result = data.Where(d => PersonList.All(p => p != d.Value));

Upvotes: 1

Roman Cerny
Roman Cerny

Reputation: 97

Answering this myself as I've been looking into the problem from wrong angle. Following works as expected:

Dictionary<string, string> Data = new Dictionary<string, string>
{
    { "John", "aaa" },
    { "Tom", "bbb" },
    { "David", "ccc" }
};

List<string> PersonList = new List<string>
{
    "Tom",
    "Peter"
};

List<string> PersonListNotInDictionary = PersonList.Where(pl => !Data.ContainsKey(pl))
                                                   .ToList();

Upvotes: 2

Stefan
Stefan

Reputation: 652

It is possible that the contains doesn't work, because the items in the PersonList are other objects than the keys in your dictionary. The objects might be the same (have the same content), but if it are different object (different refences), than the contains will return false.

An example:

myObject = new myObject() { Id = 1 };

List<myObject> listOfObjects = new List<myObject>();
listOfObjects.Add(new myObject() { Id = 1 });

var result = listOfObjects.Contains(myObject); // returns false, because the item in the list is a different object than myObject

result = listOfObjects.Any(obj => obj.Id == myObject.Id); // returns true

I don't know what the PersonList consist of, but if the elements have, for instance, an Id property than you could do something like this:

var Persons = Data.Where(kvp => !PersonList.Any(person => person.Id == kvp.Key.Id))
              .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

Upvotes: 1

Tanveer Badar
Tanveer Badar

Reputation: 5524

Is it possible that you made a typo here and meant to write this instead?

// changed to kvp.Value from kvp.Key
var Persons = Data.Where(kvp => !PersonList.Contains(kvp.Value))
                  .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

This searches the values from the dictionary in the list and retains those entries which are not in the list, as per your question.

Upvotes: 4

Related Questions