Generate permutations using polymorphic method - c#

The instructions :
Please write a piece of code that takes as an input a list in which
each element is another list containing an unknown type and which
returns a list of all possible lists that can be obtained by taking
one element from each of the input lists.
For example:
[[1, 2], [3, 4]], should return: [[1, 3], [1, 4], [2, 3], [2, 4]].
[['1'], ['2'], ['3', '4' ]], should return [['1', '2', '3'], ['1',
'2', '4']].
My code:
public static void Main(string[] args)
{
//Create a list of lists of objects.
var collections = new List<List<object>>();
collections.Add(new List<object> { 1, 5, 3 });
collections.Add(new List<object> { 7, 9 });
collections.Add(new List<object> { "a", "b" });
//Get all the possible permutations
var combinations = GetPermutations(collections);
//Loop through the results and display them in console
foreach (var result in combinations)
{
result.ForEach(item => Console.Write(item + " "));
Console.WriteLine();
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
private static List<List<object>> GetPermutations(List<List<object>> collections)
{
List<List<object>> permutations = new List<List<object>>();
//Check if the input list has any data, else return the empty list.
if (collections.Count <= 0)
return permutations;
//Add the values of the first set to the empty List<List<object>>
//permutations list
foreach (var value in collections[0])
permutations.Add(new List<object> { value });
/* Skip the first set of List<List<object>> collections as it was
* already added to the permutations list, and loop through the
* remaining sets. For each set, call the AppendValues function
* to append each value in the set to the permuations list.
* */
foreach (var set in collections.Skip(1))
permutations = AppendNewValues(permutations, set);
return permutations;
}
private static List<List<object>> AppendNewValues(List<List<object>> permutations, List<object> set)
{
//Loop through the values in the set and append them to each of the
//list of permutations calculated so far.
var newCombinations = from additional in set
from value in permutations
select new List<object>(value) { additional };
return newCombinations.ToList();
}
How could I make it work with polymorphic method that returns a generic list?

Please write a piece of code that takes as an input a list in which each element is another list containing an unknown type and which returns a list of all possible lists that can be obtained by taking one element from each of the input lists.
I would have asked for clarification, something like "You mean a generic method then?"
In speaking of polymorphism, they were likely being able to write just one method and call it form any arbitrary type, something like:
public static IList<IList<T>> GetPermutations<T>(IList<IList<T>> inputLists) {
if (inputLists.Count < 2) {
// special case.
}
return _permutationHelper(0, inputLists);
}
private static IList<IList<T>> _permutationHelper<T>(int i, IList<IList<T>> inputLists) {
IList<IList<T>> returnValue = new List<IList<T>>();
if (i == inputLists.Count) {
returnValue.Add(new List<T>());
} else {
foreach (var t in inputLists[i]) {
foreach (var list in _permutationHelper(i + 1, inputLists)) {
list.Add(t);
returnValue.Add(list);
}
}
}
return returnValue;
}
It is true that your implementation would allow arbitrary types at run time, but it loses type safety. Given that it's an implementation in C#, type safety being a requirement is a safe guess - but it doesn't hurt to ask either.
Another thing of note - they could have just said they were looking for the Cartesian product of the given lists.

All I can think of is that they were not trying to mix different types in the lists(like you implemented), the types of all lists would be the same and they wanted you to write a Generic Class that would handle the problem for different types of lists, resulting in something like this:
static void Main(string[] args)
{
var intCollections = new List<List<int>>();
intCollections.Add(new List<int> { 1, 5, 3 });
intCollections.Add(new List<int> { 7, 9 });
var stringCollections = new List<List<String>>();
stringCollections.Add(new List<String> { "a", "b" });
stringCollections.Add(new List<String> { "c","d", "e" });
stringCollections.Add(new List<String> { "g", "f" });
//here you would have the "polymorphism", the same signature for different Lists types
var intCombinations = GetPermutations(intCollections);
var stringCombinations = GetPermutations(stringCollections);
foreach (var result in intCombinations)
{
result.ForEach(item => Console.Write(item + " "));
Console.WriteLine();
}
Console.WriteLine();
foreach (var result in stringCombinations)
{
result.ForEach(item => Console.Write(item + " "));
Console.WriteLine();
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
//This would be your generic implementation, basically changing from object to T and adding <T> after method
private static List<List<T>> GetPermutations<T>(List<List<T>> collections)
{
List<List<T>> permutations = new List<List<T>>();
//Check if the input list has any data, else return the empty list.
if (collections.Count <= 0)
return permutations;
//Add the values of the first set to the empty List<List<object>>
//permutations list
foreach (var value in collections[0])
permutations.Add(new List<T> { value });
/* Skip the first set of List<List<object>> collections as it was
* already added to the permutations list, and loop through the
* remaining sets. For each set, call the AppendValues function
* to append each value in the set to the permuations list.
* */
foreach (var set in collections.Skip(1))
permutations = AppendNewValues(permutations, set);
return permutations;
}
private static List<List<T>> AppendNewValues<T>(List<List<T>> permutations, List<T> set)
{
//Loop through the values in the set and append them to each of the
//list of permutations calculated so far.
var newCombinations = from additional in set
from value in permutations
select new List<T>(value) { additional };
return newCombinations.ToList();
}
This generic implementation, comparing to yours, have the advantage of type Safety, it makes sure you will not mix different object types.

Related

C# has no SortedList<T>?

I'm trying to solve a problem in which it would be useful to have a data structure like
var list = new SortedList<int>();
list.Add(3); // list = { 3 }
list.Add(1); // list = { 1, 3 }
list.Add(2); // list = { 1, 2, 3 }
int median = list[list.Length / 2];
i.e.
O(n) insertion
O(1) lookup by index
but I can't see that such a thing exists? I see that there's some confusing SortedList<T,U> and then an interface SortedList, but neither of those are what I'm looking for.
The sorted list in the .NET framework is an associative list (that is it is for key/value pairs). You can use a regular List<T> if you use its binary search functionality, which works if you keep the list sorted at all times. You can encapsulate it in an extension method:
static class SortedListExtensions {
public static void SortedAdd<T>(this List<T> list, T value) {
int insertIndex = list.BinarySearch(value);
if (value < 0) {
value = ~value;
}
list.Insert(insertIndex, value);
}
//Added bonus: a faster Contains method
public static bool SortedContains<T>(this List<T> list, T value) {
return list.BinarySearch(value) >= 0;
}
}
List<int> values = new List<int>();
values.SortedAdd(3);
values.SortedAdd(1);
values.SortedAdd(2);

Find matching KVP from Dictionary<List<enum>,string> where search key is List<enum> and return reverse partial matches

I have a Dictionary where the key is a list of enum values, and the value is a simple string.
What I need to do is using another list of enum values find the match KVP.
The curveball and reason for posting here is I also need it to return KVP if the list from my test or search list contains all the items (or enum objects) in any key in the dictionary.
example excerpt of code:
public enum fruit{ apple , orange , banana , grapes };
public class MyClass
{
public Dictionary<List<fruit>, string> FruitBaskets = new Dictionary<List<fruit>, string>;
FruitBaskets.Add(new List<fruit>{apple,orange},"Basket 1");
List<fruit> SearchList = new List<fruit>{orange,apple,grapes};
}
I need to search the dictionary for SearchList and return "Basket 1".
Note that the matching may be backwards than what you would expect for such an example as I need the key to match agains the search list and not vice versa, so extra items in the search list that are not in the key are ok.
I know I could simply iterate the dict and check one by one but I also need this to be as fast as possible as it resides in a loop that is running fairly fast.
What I am currently using is;
public Dictionary<List<fruit>, string> SearchResults;
foreach (KeyValuePair<List<fruit>, string> FruitBasket in FruitBaskets)
{
if (FruitBasket.Key.Except(SearchList).Count() == 0)
SearchResults.Add(FruitBasket);
}
Wondering if there is a better/faster way.
You need to rethink about you choice of Keys in dictionary. There are some major problem with List keys, such as:
You can't use O(1) key lookup with List
Your keys aren't immutable
You can have identical lists as keys without receiving errors, for example you can have:
var a = new[] { fruit.organge }.ToList();
var b = new[] { fruit.organge }.ToList();
fruitBasket.Add(a, "1");
fruitBasket.Add(b, "2");
But is this dictionary valid? I guess not but it depends on your requirements.
You can change Dictionary keys!
For this reasons, you need to change your dictionary key type. You can use combined Enum values instead of using a List with bitwise operators. For this to work, you need to assign powers of 2 to each enum value:
[Flags]
public Enum Fruit
{
Orange = 1,
Apple = 2,
Banana = 4,
Grape = 8
}
You have to combine these enum values to get the desired multi-value enum dictionary key effect:
For [Fruit.Orange, Fruit.Apple] you use Fruit.Orange | Fruit.Apple.
Here's a sample code for combining and decomposing values:
private static fruit GetKey(IEnumerable<fruit> fruits)
{
return fruits.Aggregate((x, y) => x |= y);
}
private static IEnumerable<fruit> GetFruits(fruit combo)
{
return Enum.GetValues(typeof(fruit)).Cast<int>().Where(x => ((int)combo & x) > 0).Cast<fruit>();
}
Now you need a function to get all combinaions (power set) of the SearchList:
private static IEnumerable<fruit> GetCombinations(IEnumerable<fruit> fruits)
{
return Enumerable.Range(0, 1 << fruits.Count())
.Select(mask => fruits.Where((x, i) => (mask & (1 << i)) > 0))
.Where(x=>x.Any())
.Select(x=> GetKey(x));
}
Using these combinations, you can lookup values from dictionary using O(1) time.
var fruitBaskets = new Dictionary<fruit, string>();
fruitBaskets.Add(GetKey(new List<fruit> { fruit.apple, fruit.orange }), "Basket 1");
List<fruit> SearchList = new List<fruit> { fruit.orange, fruit.apple, fruit.grapes };
foreach (var f in GetCombinations(SearchList))
{
if (fruitBaskets.ContainsKey(f))
Console.WriteLine(fruitBaskets[f]);
}
Consider storing your data in a different way:
var FruitBaskets = Dictionary<fruit, List<string>>();
Each entry contains elements that match at least one fruit. Conversion from your structure is as follows:
foreach (var kvp in WobblesFruitBaskets)
{
foreach (var f in kvp.Key)
{
List<string> value;
if (!FruitBaskets.TryGetValue(f, out value))
{
value = new List<string>();
FruitBaskets.Add(f, value);
}
value.Add(kvp.Value);
}
}
Now, the search would look like this: For a composed key searchList you first calculate results for single keys:
var partialResults = new Dictionary<fruit, List<string>>();
foreach (var key in searchList)
{
List<string> r;
if (FruitBaskets.TryGetValue(key, out r))
{
partialResults.Add(key, r);
}
}
Now, what is left is to compose all possible search results. This is the hardest part, which I believe is inherent to your approach: for a key with n elements you have 2n - 1 possible subkeys. You can use one of subset generating approaches from answers to this question and generate your final result:
var finalResults = new Dictionary<List<fruit>, List<string>>();
foreach (var subkey in GetAllSubsetsOf(searchList))
{
if (!subkey.Any())
{
continue; //I assume you don't want results for an empty key (hence "-1" above)
}
var conjunction = new HashSet<string>(partialResults[subkey.First()]);
foreach (var e in subkey.Skip(1))
{
conjunction.IntersectWith(partialResults[e]);
}
finalResults.Add(subkey, conjunction.ToList());
}
I've changed string to List<string> in result's value part. If there is some invariant in your approach that guarantees there will be always only one result, then it should be easy to fix that.
if you create a Dictionary from a Reference Type, you stored just the Reference (Not value), then you can't use simply FruitBaskets[XXX] (except you use the same key that you create the node of dictionary), you must iterate whole of Keys in your dictionary.
I think this function is easy and good for you:
bool Contain(List<fruit> KEY)
{
foreach (var item in FruitBaskets.Keys)
{
if (Enumerable.SequenceEqual<fruit>(KEY,item))
return true;
}
return false;
}
and this,
bool B = Contain(new List<fruit> { fruit.apple, fruit.orange }); //this is True
But if you want to consider the permutation of members, you can use this function:
bool Contain(List<fruit> KEY)
{
foreach (var item in FruitBaskets.Keys)
{
HashSet<fruit> Hkey= new HashSet<fruit>(KEY);
if (Hkey.SetEquals(item))
return true;
}
return false;
}
and here's the output:
bool B1 = Contain(new List<fruit> { fruit.orange, fruit.grapes }); // = False
bool B2 = Contain(new List<fruit> { fruit.orange, fruit.apple }); // = True
bool B3 = Contain(new List<fruit> { fruit.apple, fruit.orange }); // = True

Combinations of multiple list

I'm not completely sure that the term 'Combination' is correct, however I have a requirement to build a list of combination form one or more List. Each list will contain a varying number of elements, e.g.
List<string> lBag1 = ["1_0, 1_1, 1_3"]
List<string> lBag2 = ["11_0, 11_1, 11_8"]
List<string> lBag3 = ["3_0"]
What I need is all combination of the Lists form 1 to n elements with no more than one element from each list, e.g.
"1_0"
"1_1"
"1_3"
"11_0"
"11_1"
"11_8"
"3_0"
"1_0 11_0"
"1_0 11_1"
"1_0 11_8"
"1_0 3_0"
...
"1_3 11_8 3_0"
Order is not important, so "1_0 11_0" is considered the same as "11_0 1_0".
Any assistance would be greatly appreciated
These two extension methods will let you chain together several enumerations, calculating the combinations you want.
Each combination is an enumeration, rather than a concatenated string.
// This method takes two sequences of T, and returns
// - each element of the first sequence,
// wrapped in its own one-element sequence
// - each element of the second sequence,
// wrapped in its own one-element sequence
// - each pair of elements (one from each sequence),
// as a two-element sequence.
// e.g. { 1 }.CrossWith({ 2 }) returns { { 1 }, { 2 }, { 1, 2 } }
public static IEnumerable<IEnumerable<T>> CrossWith<T>(
this IEnumerable<T> source1,
IEnumerable<T> source2)
{
foreach(T s1 in source1) yield return new[] { s1 };
foreach(T s2 in source2) yield return new[] { s2 };
foreach(T s1 in source1)
foreach(T s2 in source2)
yield return new[] { s1, s2 };
}
// This method takes a sequence of sequences of T and a sequence of T,
// and returns
// - each sequence from the first sequence
// - each element of the second sequence,
// wrapped in its own one-element sequence
// - each pair, with the element from the second sequence appended to the
// sequence from the first sequence.
// e.g. { { 1, 2 } }.CrossWith({ 3 }) returns
// { { 1, 2 }, { 3 }, { 1, 2, 3 } }
public static IEnumerable<IEnumerable<T>> CrossWith<T>(
this IEnumerable<IEnumerable<T>> source1,
IEnumerable<T> source2)
{
foreach(IEnumerable<T> s1 in source1) yield return s1;
foreach(T s2 in source2) yield return new[] { s2 };
foreach(IEnumerable<T> s1 in source1)
foreach(T s2 in source2)
yield return s1.Concat(new[] { s2 }).ToArray();
}
var cross = lBag1.CrossWith(lBag2).CrossWith(lBag3);
// { "1_0" }, { "1_1" }, { "1_3" } ...
// ... { "1_0", "11_0" }, ...
Alternatively, there is this classic Eric Lippert blog post that does a similar thing. (Similar result, very different method.)
Does this work for you:
var empty = new string[] { null, };
var query =
from b1 in empty.Concat(lBag1)
from b2 in empty.Concat(lBag2)
from b3 in empty.Concat(lBag3)
let bs = new [] { b1, b2, b3 }.Where(b => b != null)
let result = String.Join(" ", bs)
where result != ""
select result;
This is only my opinion. You have to decide by your own how to implement it, but i would:
1) Create a class to represent your pairs X_Y
2) Make your class Implement IEquatable
3) Provide implementations for Equal
4) Implement a constructor that, given a string in the form X_Y returns a YourClass object.
5) Implement a public static function that, given a string containing comma separatd list of X_Y returns a List
6) Use the previous method to create three list.
7) Create an empty List
8) Use yourList.Append to add elements from the trhee lists.
May be I use guns to kill flies.

Finding differences in two lists

I am thinking about a good way to find differences in two lists
here is the problem:
Two lists have some strings where first 3 numbers/characters (*delimited) represent the unique key(followed by the text String="key1*key2*key3*text").
here is the string example:
AA1*1D*4*The quick brown fox*****CC*3456321234543~
where "*AA1*1D*4*" is a unique key
List1: "index1*index2*index3", "index2*index2*index3", "index3*index2*index3"
List2: "index2*index2*index3", "index1*index2*index3", "index3*index2*index3", "index4*index2*index3"
I need to match indexes in both lists and compare them.
If all 3 indexes from 1 list match 3 indexes from another list, I need to track both string entries in the new list
If there is a set of indexes in one list that don't appear in another, I need to track one side and keep an empty entry in another side. (#4 in the example above)
return the list
This is what I did so far, but I am kind of struggling here:
List<String> Base = baseListCopy.Except(resultListCopy, StringComparer.InvariantCultureIgnoreCase).ToList(); //Keep unique values(keep differences in lists)
List<String> Result = resultListCopy.Except(baseListCopy, StringComparer.InvariantCultureIgnoreCase).ToList(); //Keep unique values (keep differences in lists)
List<String[]> blocksComparison = new List<String[]>(); //we container for non-matching blocks; so we could output them later
//if both reports have same amount of blocks
if ((Result.Count > 0 || Base.Count > 0) && (Result.Count == Base.Count))
{
foreach (String S in Result)
{
String[] sArr = S.Split('*');
foreach (String B in Base)
{
String[] bArr = B.Split('*');
if (sArr[0].Equals(bArr[0]) && sArr[1].Equals(bArr[1]) && sArr[2].Equals(bArr[2]) && sArr[3].Equals(bArr[3]))
{
String[] NA = new String[2]; //keep results
NA[0] = B; //[0] for base
NA[1] = S; //[1] for result
blocksComparison.Add(NA);
break;
}
}
}
}
could you suggest a good algorithm for this process?
Thank you
You can use a HashSet.
Create a HashSet for List1. remember index1*index2*index3 is diffrent from index3*index2*index1.
Now iterate through second list.
Create Hashset for List1.
foreach(string in list2)
{
if(hashset contains string)
//Add it to the new list.
}
If I understand your question correctly, you'd like to be able to compare the elements by their "key" prefix, instead by the whole string content. If so, implementing a custom equality comparer will allow you to easily leverage the LINQ set algorithms.
This program...
class EqCmp : IEqualityComparer<string> {
public bool Equals(string x, string y) {
return GetKey(x).SequenceEqual(GetKey(y));
}
public int GetHashCode(string obj) {
// Using Sum could cause OverflowException.
return GetKey(obj).Aggregate(0, (sum, subkey) => sum + subkey.GetHashCode());
}
static IEnumerable<string> GetKey(string line) {
// If we just split to 3 strings, the last one could exceed the key, so we split to 4.
// This is not the most efficient way, but is simple.
return line.Split(new[] { '*' }, 4).Take(3);
}
}
class Program {
static void Main(string[] args) {
var l1 = new List<string> {
"index1*index1*index1*some text",
"index1*index1*index2*some text ** test test test",
"index1*index2*index1*some text",
"index1*index2*index2*some text",
"index2*index1*index1*some text"
};
var l2 = new List<string> {
"index1*index1*index2*some text ** test test test",
"index2*index1*index1*some text",
"index2*index1*index2*some text"
};
var eq = new EqCmp();
Console.WriteLine("Elements that are both in l1 and l2:");
foreach (var line in l1.Intersect(l2, eq))
Console.WriteLine(line);
Console.WriteLine("\nElements that are in l1 but not in l2:");
foreach (var line in l1.Except(l2, eq))
Console.WriteLine(line);
// Etc...
}
}
...prints the following result:
Elements that are both in l1 and l2:
index1*index1*index2*some text ** test test test
index2*index1*index1*some text
Elements that are in l1 but not in l2:
index1*index1*index1*some text
index1*index2*index1*some text
index1*index2*index2*some text
List one = new List();
List two = new List();
List three = new List();
HashMap<String,Integer> intersect = new HashMap<String,Integer>();
for(one: String index)
{
intersect.put(index.next,intersect.get(index.next) + 1);
}
for(two: String index)
{
if(intersect.containsKey(index.next))
{
three.add(index.next);
}
}

How to iterate through two collections of the same length using a single foreach

I know this question has been asked many times before but I tried out the answers and they don't seem to work.
I have two lists of the same length but not the same type, and I want to iterate through both of them at the same time as list1[i] is connected to list2[i].
Eg:
Assuming that i have list1 (as List<string>) and list2 (as List<int>)
I want to do something like
foreach( var listitem1, listitem2 in list1, list2)
{
// do stuff
}
Is this possible?
This is possible using .NET 4 LINQ Zip() operator or using open source MoreLINQ library which provides Zip() operator as well so you can use it in more earlier .NET versions
Example from MSDN:
int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
// The following example concatenates corresponding elements of the
// two input sequences.
var numbersAndWords = numbers.Zip(words, (first, second) => first + " " + second);
foreach (var item in numbersAndWords)
{
Console.WriteLine(item);
}
// OUTPUT:
// 1 one
// 2 two
// 3 three
Useful links:
Soure code of the MoreLINQ Zip() implementation: MoreLINQ Zip.cs
Edit - Iterating whilst positioning at the same index in both collections
If the requirement is to move through both collections in a 'synchronized' fashion, i.e. to use the 1st element of the first collection with the 1st element of the second collection, then 2nd with 2nd, and so on, without needing to perform any side effecting code, then see #sll's answer and use .Zip() to project out pairs of elements at the same index, until one of the collections runs out of elements.
More Generally
Instead of the foreach, you can access the IEnumerator from the IEnumerable of both collections using the GetEnumerator() method and then call MoveNext() on the collection when you need to move on to the next element in that collection. This technique is common when processing two or more ordered streams, without needing to materialize the streams.
var stream1Enumerator = stream1.GetEnumerator();
var stream2Enumerator = stream2.GetEnumerator();
var currentGroupId = -1; // Initial value
// i.e. Until stream1Enumerator runs out of
while (stream1Enumerator.MoveNext())
{
// Now you can iterate the collections independently
if (stream1Enumerator.Current.Id != currentGroupId)
{
stream2Enumerator.MoveNext();
currentGroupId = stream2Enumerator.Current.Id;
}
// Do something with stream1Enumerator.Current and stream2Enumerator.Current
}
As others have pointed out, if the collections are materialized and support indexing, such as an ICollection interface, you can also use the subscript [] operator, although this feels rather clumsy nowadays:
var smallestUpperBound = Math.Min(collection1.Count, collection2.Count);
for (var index = 0; index < smallestUpperBound; index++)
{
// Do something with collection1[index] and collection2[index]
}
Finally, there is also an overload of Linq's .Select() which provides the index ordinal of the element returned, which could also be useful.
e.g. the below will pair up all elements of collection1 alternatively with the first two elements of collection2:
var alternatePairs = collection1.Select(
(item1, index1) => new
{
Item1 = item1,
Item2 = collection2[index1 % 2]
});
Short answer is no you can't.
Longer answer is that is because foreach is syntactic sugar - it gets an iterator from the collection and calls Next on it. This is not possible with two collections at the same time.
If you just want to have a single loop, you can use a for loop and use the same index value for both collections.
for(int i = 0; i < collectionsLength; i++)
{
list1[i];
list2[i];
}
An alternative is to merge both collections into one using the LINQ Zip operator (new to .NET 4.0) and iterate over the result.
foreach(var tup in list1.Zip(list2, (i1, i2) => Tuple.Create(i1, i2)))
{
var listItem1 = tup.Item1;
var listItem2 = tup.Item2;
/* The "do stuff" from your question goes here */
}
It can though be such that much of your "do stuff" can go in the lambda that here creates a tuple, which would be even better.
If the collections are such that they can be iterated, then a for() loop is probably simpler still though.
Update: Now with the built-in support for ValueTuple in C#7.0 we can use:
foreach ((var listitem1, var listitem2) in list1.Zip(list2, (i1, i2) => (i1, i2)))
{
/* The "do stuff" from your question goes here */
}
You can wrap the two IEnumerable<> in helper class:
var nums = new []{1, 2, 3};
var strings = new []{"a", "b", "c"};
ForEach(nums, strings).Do((n, s) =>
{
Console.WriteLine(n + " " + s);
});
//-----------------------------
public static TwoForEach<A, B> ForEach<A, B>(IEnumerable<A> a, IEnumerable<B> b)
{
return new TwoForEach<A, B>(a, b);
}
public class TwoForEach<A, B>
{
private IEnumerator<A> a;
private IEnumerator<B> b;
public TwoForEach(IEnumerable<A> a, IEnumerable<B> b)
{
this.a = a.GetEnumerator();
this.b = b.GetEnumerator();
}
public void Do(Action<A, B> action)
{
while (a.MoveNext() && b.MoveNext())
{
action.Invoke(a.Current, b.Current);
}
}
}
Instead of a foreach, why not use a for()? for example...
int length = list1.length;
for(int i = 0; i < length; i++)
{
// do stuff with list1[i] and list2[i] here.
}

Categories