Finding an item in a complex object

Multi tool use
Finding an item in a complex object
I have a sequence of elements
string:
new string { "A", "B", "C", "D" }
And there is also an object consisting of such several sequences
object:
List<Test> obj = new List<Test>()
{
new Test() {Lists = new List<string>() { "A", "B" } },
new Test() {Lists = new List<string>() { "A", "C" } },
new Test() {Lists = new List<string>() { "C" } }
};
I want to find the missing element ("D") in all object collections.
That's what I got:
private static List<string> FindeMissingElements()
{
string nonExistentElement = null;
List<string> nonExistentElements = new List<string>();
foreach (var elemArr in arr)
{
foreach (var elemObj in obj)
{
if (elemObj.Lists.Any(a => a.Contains(elemArr)))
{
nonExistentElement = null;
break;
}
nonExistentElement = elemArr;
}
if (nonExistentElement != null)
nonExistentElements.Add(nonExistentElement);
}
return nonExistentElements;
}
I would like to simplify the code and use LINQ if possible...
This is a perfectly valid question for SO.
– oɔɯǝɹ
Jun 30 at 10:58
4 Answers
4
First, I would flatten the sources into a list so I have a collection of actual values. To do this, it's best to use SelectMany
(tests
is the original list, and domain
is the array of possible elements)
SelectMany
tests
domain
var sourceElements = tests.SelectMany(test => test.Lists);
This will get the Lists
properties for each test, and join all the results together, so in your example, you'll have a result of
Lists
["A", "B", "A", "C", "C"]
You can use Distinct
to only get unique items, so the code is
Distinct
var sourceElements = tests.SelectMany(test => test.Lists).Distinct();
Now, the only thing left to do is to find the items that are in the domain
but not in the sourceElements
, i.e. their set difference. That can easily be done with the Except
method.
domain
sourceElements
Except
var missing = domain.Except(sourceElements);
So, to put everything together, your method should be:
private static IEnumerable<string> FindMissingElements(
IEnumerable<Test> tests, IEnumerable<string> domain)
{
var sourceElements = tests.SelectMany(test => test.Lists).Distinct();
var missing = domain.Except(sourceElements)
return missing;
}
Here is a working example.
Thank you for a beautiful decision. Can you recommend a book / sites on LIQN?
– Tibomso
Jul 1 at 12:38
I think this can help you:
var list1 = new string { "A", "B", "C", "D" }
var nonExistentElements = new List<string>(list1);
obj.ForEach(o => nonExistentElements = nonExistentElements.Except(o.Lists).ToList());
And what if one of the lists of the object is null?
– Tibomso
Jul 1 at 12:17
@Tibomso According to the problem logic, null must be returned if null is not your choice list. but if you don't want it, you can omit it as an exception.
– Amin
2 days ago
I Try and test your question like this:
private static List<string> FindeMissingElements()
{
var objectArray = new {"A", "B", "C", "D"};
var obj = new List<Test>()
{
new Test() {Lists = new List<string>() { "A", "B" } },
new Test() {Lists = new List<string>() { "A", "C" } },
new Test() {Lists = new List<string>() { "C" } }
};
var missingValues = objectArray.Where(x => !obj.Any(c => c.Lists.Any(v => v == x))).ToList();
return missingValues.any() ? missingValue:missingValue = new List<string>();
}
With 1 row you can find missing value.
GoodLuck.
//Flatten the complex object - Get all the elements from the complex object into an IEnumerable collection
//Flatten the list --
var listB = (from lm in obj select lm.Lists).SelectMany(it => it.ToList());
//Below list A is input elements
//use IEnumerable except extension as below - missingElements IEnumerable will have your elements from complex object --
string listA = new string { "A", "B", "C", "D", "E" };
var missinElements = listA.Except(listB);
While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.
– Narendra Jadhav
Jun 30 at 11:09
just added some comments
– Kaushik Srinath
Jun 30 at 11:17
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
I'm voting to close this question as off-topic because it belongs on Code Review, not SO
– Stephen Muecke
Jun 30 at 10:35