'join 2 lists and create one to many relationship [closed]
Is it possible to join 2 lists and create one to many relationship?
For example,
list 1:
{"High", "Med", "Low"}
list 2:
{"Submitted", "In Progress", "Draft", "Rejected"}
final list, I will have values like this:
{
{"High", "Submitted"}, {"High", "In Progress"},{"High", "Draft"}, {"High", "Rejected"},
{"Med", "Submitted"}, {"Med", "In Progress"},{"Med", "Draft"}, {"Med", "Rejected"},
{"Low", "Submitted"}, {"Low", "In Progress"},{"Low", "Draft"}, {"Low", "Rejected"}
}
Solution 1:[1]
Not sure if this is what you are looking for, but you can use Select and SelectMany to create the final List of KeyVaulePair.
var list1 = new List<string>() { "High", "Medium", "Low" };
var list2 = new List<string>() { "Submitted", "In-Progress", "Draft", "Rejected" };
var joined = list1.SelectMany(val1 => list2.Select(val2 => new KeyValuePair<string, string>(val1, val2)));
foreach(var res in joined)
{
Console.WriteLine(res.Key + "," + res.Value);
}
If you want to use imperative style of coding, then just create 2 for loops
Solution 2:[2]
It seems, that you are looking for a Cartesian Join, you can do it with a help of Linq:
var list1 = new List<string>() {
"High", "Medium", "Low" };
var list2 = new List<string>() {
"Submitted", "In-Progress", "Draft", "Rejected" };
// I've combined values as named tuple: (string first, string second)
// but you can use anonymous class, or just concat string strings
var joined = list1
.SelectMany(item1 => list2.Select(item2 => (first: item1, second: item2)));
.ToList();
Let's have a look:
Console.Write(string.Join(Environment.NewLine, joined));
Outcome:
(High, Submitted)
(High, In-Progress)
(High, Draft)
(High, Rejected)
(Medium, Submitted)
(Medium, In-Progress)
(Medium, Draft)
(Medium, Rejected)
(Low, Submitted)
(Low, In-Progress)
(Low, Draft)
(Low, Rejected)
Solution 3:[3]
LINQ method syntax for joins is pretty ugly and even counterintuitive, IMHO; query syntax looks much nicer/easier to read:
from s in list1
from t in list2
select new { s, t }
Or as a tuple:
from s in list1
from t in list2
select ( s, t )
Solution 4:[4]
If you want to do Cartesian product and want to store it in text-value pair then you can use List with SelectListItem. It will give you list with text-value pair.
var list1 = new List<string>() { "High", "Medium", "Low" };
var list2 = new List<string>() { "Submitted", "In-Progress", "Draft", "Rejected" };
List<SelectListItem> list3 = new List<SelectListItem>();
foreach (string str in list1)
{
foreach(string str2 in list2)
{
list3.Add(new SelectListItem()
{ Text = str, Value = str2 });
}
}
Solution 5:[5]
You can use the join method from LINQ:
List<(string,string)> joined = list1.Join(list2, x => true, y => true, (x,y) => (x,y)).ToList();
The second and third parameter are selectors for list1 and list2. If both are the same, a joined value will be created. If we give the same constant value for both selectors, the joining condition is always fulfilled and hence all possible pairs are created.
Online demo: https://dotnetfiddle.net/JaK6ff
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Pratik Bhattacharya |
| Solution 2 | Dmitry Bychenko |
| Solution 3 | Caius Jard |
| Solution 4 | Karnav Modi |
| Solution 5 |
