I am wanting to find the cartesian product from several lists:
var list1 = new List<int> { 1, 2, 3};
var list2 = new List<string> { "A" };
var list3 = new List<int>();
The end result I am trying to get is a list of objects with every possible combination:
{ list1Value: 1, list2Value: "A", list3Value: null },
{ list1Value: 2, list2Value: "A", list3Value: null },
{ list1Value: 3, list2Value: "A", list3Value: null }
To accomplish this I am using linq query syntax:
var combinations = from value1 in list1
from value2 in list2
from value3 in list3
select new Combination
{
List1Value: value1,
List2Value: value2,
List3Value: value3
}
However, because list3
is empty, combinations
also is empty. If I give list3
at least 1 item then everything works correctly. How can I handle the empty lists in the query syntax so that it still selects from the other lists?
CodePudding user response:
Here you go:
var list1 = new List<int> { 1, 2, 3 };
var list2 = new List<string> { "A" };
var list3 = new List<int>();
var combinations =
from value1 in list1
from value2 in list2
from value3 in
list3
.Select(x => (int?)x)
.DefaultIfEmpty()
select new
{
List1Value = value1,
List2Value = value2,
List3Value = value3
};
The key change is to use .Select(x => (int?)x)
which turns an int
into a int?
that then allows .DefaultIfEmpty()
to return null
, thus making the output clear when the value was missing.
The output I get is:
If I make this change:
var list3 = new List<int>() { 0, 4 };
...then the output becomes:
CodePudding user response:
Seems you are trying to bind null
or empty
list on another list as you have shown above. But in that case you should need a little modification of your existing list defination which is like below:
Your Given List:
var list1 = new List<int> { 1, 2, 3};
var list2 = new List<string> { "A" };
var list3 = new List<int>();
Required Modification:
var list3 = new List<int?>();
Why The Modification Required :
As you wanted to bind your final list with nullable
value which output should be like below:
Note:
So you have to tell the compiler that you are going to bind list with nullable value.
Final Code Snippet :
var list1 = new List<int> { 1, 2, 3 };
var list2 = new List<string> { "A" };
var list3 = new List<int?>();
var combinations = from value1 in list1
from value2 in list2
from value3 in list3.DefaultIfEmpty()
select new
{
list1 = value1,
list2 = value2,
list3 = value3 == 0 ? "" : null
};
foreach (var item in combinations)
{
Console.WriteLine(item);
}
Note:
If you stikely want to print output asnull
. then replace theternary
operator like this:list3 = value3 == 0 ? null : "null"
. It would generate that as well.
If you want to master on linq
I would suggest you to check our official document here. Hope it would help you accordingly.