I would like to check whether first array match with second array items, the second array have texts that I want to match with the first array.
Here is the code that I am using:
public static void Main()
{
List<string> FirstArrayToLookup = new List<string>();
List<string> SecondArrayToLookup = new List<string>();
List<string> ThirdArrayToLookup = new List<string>();
FirstArrayToLookup.Add("FirstArray1");
FirstArrayToLookup.Add("FirstArray2");
SecondArrayToLookup.Add("SecondArray1");
ThirdArrayToLookup.Add("ThirdArray1");
ThirdArrayToLookup.Add("ThirdArray2");
ThirdArrayToLookup.Add("ThirdArray3");
string[] FirstStringContains = { "Array1", "Array2" };
string[] SecondStringContains = { "Array1" };
string[] ThirdStringContains = { "Array1", "Array2", "Array3" };
if (FirstArrayToLookup.All(x => FirstStringContains.All(y => x.Contains(y))))
Console.WriteLine("First Array to Lookup");
if (SecondArrayToLookup.All(x => SecondStringContains.All(y => x.Contains(y))))
Console.WriteLine("Second Array to Lookup");
if (ThirdArrayToLookup.All(x => ThirdStringContains.All(y => x.Contains(y))))
Console.WriteLine("Third Array to Lookup");
}
The above code will only return Second Array to Lookup
, where what I want to achieve is if the FirstArrayToLookup
variable match with the FirstStringContains
variable (which it does as because FirstArrayToLookup
does have items which has the word of Array1
and Array2
, same goes with their check condition FirstStringContains
), then it should return First Array to Lookup
, same goes with the others. However only the Second Array to Lookup
is returned, but not First Array to Lookup
and Third Array to Lookup
. The FirstArrayToLookup
have to be match with FirstStringContains
, same goes with others.
Basically, from user point of view, as because the FirstArrayToLookup
has Array1
and Array2
, and it check against the FirstStringContains
that has Array1
and Array2
also which fulfills the condition, it should print First Array to Lookup
, same goes with others as it is check against their respective ArrayToLookup
with StringContains
variable
.Net fiddle: https://dotnetfiddle.net/rhTMuz
Anyone knows on how to solve this?
UPDATE:
I have tried to use as according to the following question: Link , which uses the if else conditions, however it does not fulfills what I want, which is it should print First Array to Lookup
, Second Array to Lookup
and Third Array to Lookup
, as because FirstArrayToLookup
does contains Array1
and Array2
items inside them and their check against does contains Array1
and Array2
items as well inside them, same goes with SecondArrayToLookup
with their check SecondStringContains
, and ThirdArrayToLookup
with their check ThirdStringContains
. Currently it only returns Second Array to Lookup
which only fulfills the condition of SecondArrayToLookup
with their check SecondStringContains
.Net Fiddle: https://dotnetfiddle.net/5DZpfL
Thank you
CodePudding user response:
Let's take a look at one of the statements that doesn't evaluate to true:
if (FirstArrayToLookup.All(x => FirstStringContains.All(y => x.Contains(y))))
Console.WriteLine("First Array to Lookup");
Specifically this secondary .All()
query, using the first value contained in FirstArrayToLookup
("FirstArray1"
):
FirstStringContains.All(y => x.Contains(y))
This is saying "for the values contained in FirstStringContains
("Array1"
, "Array2"
) does "FirstArray1"
contain ALL of these values?" So, does the literal value of "FirstArray1"
contain both "Array1"
AND "Array2"
? It only contains "Array1"
, thus the evaluation of false for that statement.
The second statement is returning true because there is only one value to check against one value.
CodePudding user response:
If you strictly want to match the two sequences element by element (e.g. check whether the first element in FirstArrayToLookup
contains the first element in FirstStringContains
and the second element in FirstArrayToLookup
contains the second element in FirstStringContains
; and so on), you can use Enumerable.Zip()
to perform element-wise comparison.
For the First*
-scenario, you could do:
var allMatch = FirstArrayToLookup
.Zip(FirstStringContains,
( lookupValue, searchValue ) => lookupValue.Contains(searchValue))
.All(isMatch => isMatch);
The element-wise comparison would then look as follows for the first element:
( "FirstArray1", "Array1" ) => "FirstArray1".Contains("Array1"))
and as follows for the second element:
( "FirstArray2", "Array2" ) => "FirstArray2".Contains("Array2"))
Seeing as both .Contains()
will return true
, the following .All(isMatch => isMatch)
will also return true
.
.Zip()
will process the two sequences in parallel until the shortest (if any) sequence ends. Therefore, if either sequence is longer than the other (and by that, it is guaranteed that there's not a full element-by-element match), that needs to be addressed before using the .Zip()
operation.
I would suggest to create a method, something like the following:
private static bool IsElementWiseMatch(List<string> lookupValues, string[] searchValues)
{
if (lookupValues.Count != searchValues.Length)
{
return false;
}
return lookupValues
.Zip(searchValues,
( lookupValue, searchValue ) => lookupValue.Contains(searchValue))
.All(isMatch => isMatch);
}
and call it for each sequence pair:
if (IsElementWiseMatch(FirstArrayToLookup, FirstStringContains))
{
Console.WriteLine("First Array to Lookup");
}
Example fiddle here.