I have this piece of code, which seems to support passing into it many list arguments and it would compare each one against each other one to find a common list among all of the other lists simultaneously.
I cannot figure out how to pass multiple Lists into a single argument thats a IEnmerable.
Say my test code looks like this
List<uint> List1 = new List<uint>();
List<uint> List2 = new List<uint>();
List<uint> List3 = new List<uint>();
List<uint> Commons = FindCommon(List1, List2, List3); //no compile
List<uint> Commons = FindCommon<List<uint>>(List1, List2, List3); //no compile?? why
How do I call this properly?? must I merge them somehow into a IEnumerable?? or must I somehow combine them all into 1 list yet keeping some kind of invisible divider?
static List<T> FindCommon<T>(IEnumerable<List<T>> lists)
{
Dictionary<T, int> map = new Dictionary<T, int>();
int listCount = 0; // number of lists
foreach (IEnumerable<T> list in lists)
{
listCount++;
foreach (T item in list)
{
// Item encountered, increment count
int currCount;
if (!map.TryGetValue(item, out currCount))
currCount = 0;
currCount++;
map[item] = currCount;
}
}
List<T> result= new List<T>();
foreach (KeyValuePair<T,int> kvp in map)
{
// Items whose occurrence count is equal to the number of lists are common to all the lists
if (kvp.Value == listCount)
result.Add(kvp.Key);
}
return result;
}
P.S.> FindCommon is broken somehow it doesn't work properly, probably isn't intended what I thought it should do.. it doesn't check all lists simultaneously together only linear one list at a time with another list which breaks it's purpose, it counts them up.. but it doesn't keep track from which list they came from.
Fixed it like so, this method worked as intended.
public static List<T> FindCommon<T>(params List<T>[] lists)
{
SortedDictionary<T, bool>
current_common = new SortedDictionary<T, bool>(),
common = new SortedDictionary<T, bool>();
foreach (List<T> list in lists)
{
if (current_common.Count == 0)
{
foreach (T item in list)
{
common[item] = true;
}
}
else
{
foreach (T item in list)
{
if (current_common.ContainsKey(item))
{
common[item] = true;
}
}
}
if (common.Count == 0)
{
current_common.Clear();
break;
}
SortedDictionary<T, bool>
swap = current_common;
current_common = common;
common = swap;
common.Clear();
}
return new List<T>(current_common.Keys);
}
You can accomplish this nicely using the params
keyword. In your example:
static List<T> FindCommon<T>(params List<T>[] lists)
That would achieve usage:
List<uint> Commons = FindCommon(List1, List2, List3);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With