What (if any) is the C# equivalent of Python's itertools.chain method?
Python Example:
l1 = [1, 2]
l2 = [3, 4]
for v in itertools.chain(l1, l2):
print(v)
Results:
1
2
3
4
Note that I'm not interested in making a new list that combines my first two and then processing that. I want the memory/time savings that itertools.chain provides by not instantiating this combined list.
You could do the same on C# by using the Concat extension method from LINQ:
l1.Concat(l2)
LINQ uses a deferred execution model, so this won't create a new list.
Enumerable.Concat (MSDN)
var l1 = new List<int>() { 1, 2 };
var l2 = new List<int>() { 3, 4 };
foreach(var item in Enumerable.Concat(l1, l2))
{
Console.WriteLine(item.ToString())
}
I've started building my own c# equivalent of itertools. Here is what I came up with for chain. Nice and succinct and keeps some of the Python charm. Here are two implementations of Chain. It seems the compiler can't distinguish between the call signatures, so use the one that best suites you.
public static IEnumerable<T> Chain<T>(IEnumerable<IEnumerable<T>> collection)
{
foreach (var innerCollection in collection)
{
foreach (var item in innerCollection)
{
yield return item;
}
}
}
public static IEnumerable<T> Chain<T>(params IEnumerable<T>[] collection)
{
foreach (var innerCollection in collection)
{
foreach (var item in innerCollection)
{
yield return item;
}
}
}
Related
Is there a method that inserts an object between each object in an array?
For example, given an array of non-zero integers, is there a way to insert 0 in between each element? E.g. change [1, 2, 3] to [1, 0, 2, 0, 3]?
Specifically, I am looking to do something declarative like String.Join(0, [1, 2, 3]), but with arbitrary arrays (not just char arrays). A non-declarative way would be something like this:
public static IList<T> InterleaveWith<T>( this IList<T> #this, T divider ) {
IList<T> joined = new List<T>( #this.Count * 2 );
foreach( T item in #this ) {
joined.Add( item );
joined.Add( divider );
}
joined.RemoveAt( joined.Count - 1 );
return joined;
}
There is no built-in method, but you can do it easily with yield return:
static IEnumerable<T> Join<T>(T separator, IEnumerable<T> items) {
bool first = true;
foreach (var item in items) {
if (!first) {
yield return separator;
} else {
first = false;
}
yield return item;
}
}
Demo.
The approach that uses as much built-in functionality as available would be to use SelectMany:
static IEnumerable<T> Join<T>(this IEnumerable<T> items, T separator) =>
items.SelectMany((item, index) =>
index == 0 ? new[] { item } : new[] { separator, item });
Realistically though, I'd probably go for a custom implementation similar to what #dasblinkenlight wrote up.
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.
This is my first go at coding in C# - I have a background in C/Python/Javascript/Haskell.
Why does the program below work? I would expect this to work in Haskell, as lists are immutable, but I am struggling with how I can use the same iterator nums twice, without error.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
var nums = new List<int?>() { 0, 0, 2, 3, 3, 3, 4 };
var lastNums = new List<int?>() { null } .Concat(nums);
var changesAndNulls = lastNums.Zip(nums,
(last, curr) => (last == null || last != curr) ? curr : null
);
var changes = from changeOrNull in changesAndNulls where changeOrNull != null select changeOrNull;
foreach (var change in changes) {
Console.WriteLine("change: " + change);
}
}
}
}
In your code nums is not IEnumerator<T> (iterator), it's IEnumarable<T> and IEnumarable <T> has GetEnumerator() method which can be invoked as many times as required:
IEnumerable<int?> nums = new List<int?>() { 0, 0, 2, 3, 3, 3, 4 };
// Linq gets enumerator to do Concat
using (var iterator1 = nums.GetEnumerator()) {
while (iterator1.MoveNext()) {
...
}
}
...
// Linq gets (fresh!) enumerator to do Zip
using (var iterator2 = nums.GetEnumerator()) {
while (iterator2.MoveNext()) {
...
}
}
So IEnumerable<T> is a factory producing IEnumerator<T> instances (and it is a IEnumerator<T> that can't be re-used)
A List<int?> implements the interface IEnumerable<int?>. That means it has a method called GetEnumerator().
This method returns a new Enumerator<int?> object used to iterate over all the items.
You are calling GetEnumerator() (in the background) when you use it inside a foreach loop or when you call one of the many extension methods like Concat() (which call GetEnumerator() themselves).
I suggest you take a tutorial on C#. It is a very different language than Haskell and it has some very unique features.
Just for starters: http://en.wikipedia.org/wiki/C_Sharp_syntax
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.
}
Is there a way to do foreach style iteration over parallel enumerables in C#? For subscriptable lists, I know one could use a regular for loop iterating an int over the index range, but I really prefer foreach to for for a number of reasons.
Bonus points if it works in C# 2.0
.NET 4's BlockingCollection makes this pretty easy. Create a BlockingCollection, return its .GetConsumingEnumerable() in the enumerable method. Then the foreach simply adds to the blocking collection.
E.g.
private BlockingCollection<T> m_data = new BlockingCollection<T>();
public IEnumerable<T> GetData( IEnumerable<IEnumerable<T>> sources )
{
Task.Factory.StartNew( () => ParallelGetData( sources ) );
return m_data.GetConsumingEnumerable();
}
private void ParallelGetData( IEnumerable<IEnumerable<T>> sources )
{
foreach( var source in sources )
{
foreach( var item in source )
{
m_data.Add( item );
};
}
//Adding complete, the enumeration can stop now
m_data.CompleteAdding();
}
Hope this helps.
BTW I posted a blog about this last night
Andre
Short answer, no. foreach works on only one enumerable at a time.
However, if you combine your parallel enumerables into a single one, you can foreach over the combined. I am not aware of any easy, built in method of doing this, but the following should work (though I have not tested it):
public IEnumerable<TSource[]> Combine<TSource>(params object[] sources)
{
foreach(var o in sources)
{
// Choose your own exception
if(!(o is IEnumerable<TSource>)) throw new Exception();
}
var enums =
sources.Select(s => ((IEnumerable<TSource>)s).GetEnumerator())
.ToArray();
while(enums.All(e => e.MoveNext()))
{
yield return enums.Select(e => e.Current).ToArray();
}
}
Then you can foreach over the returned enumerable:
foreach(var v in Combine(en1, en2, en3))
{
// Remembering that v is an array of the type contained in en1,
// en2 and en3.
}
Zooba's answer is good, but you might also want to look at the answers to "How to iterate over two arrays at once".
I wrote an implementation of EachParallel() from the .NET4 Parallel library. It is compatible with .NET 3.5: Parallel ForEach Loop in C# 3.5
Usage:
string[] names = { "cartman", "stan", "kenny", "kyle" };
names.EachParallel(name =>
{
try
{
Console.WriteLine(name);
}
catch { /* handle exception */ }
});
Implementation:
/// <summary>
/// Enumerates through each item in a list in parallel
/// </summary>
public static void EachParallel<T>(this IEnumerable<T> list, Action<T> action)
{
// enumerate the list so it can't change during execution
list = list.ToArray();
var count = list.Count();
if (count == 0)
{
return;
}
else if (count == 1)
{
// if there's only one element, just execute it
action(list.First());
}
else
{
// Launch each method in it's own thread
const int MaxHandles = 64;
for (var offset = 0; offset < list.Count() / MaxHandles; offset++)
{
// break up the list into 64-item chunks because of a limitiation // in WaitHandle
var chunk = list.Skip(offset * MaxHandles).Take(MaxHandles);
// Initialize the reset events to keep track of completed threads
var resetEvents = new ManualResetEvent[chunk.Count()];
// spawn a thread for each item in the chunk
int i = 0;
foreach (var item in chunk)
{
resetEvents[i] = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(new WaitCallback((object data) =>
{
int methodIndex = (int)((object[])data)[0];
// Execute the method and pass in the enumerated item
action((T)((object[])data)[1]);
// Tell the calling thread that we're done
resetEvents[methodIndex].Set();
}), new object[] { i, item });
i++;
}
// Wait for all threads to execute
WaitHandle.WaitAll(resetEvents);
}
}
}
If you want to stick to the basics - I rewrote the currently accepted answer in a simpler way:
public static IEnumerable<TSource[]> Combine<TSource> (this IEnumerable<IEnumerable<TSource>> sources)
{
var enums = sources
.Select (s => s.GetEnumerator ())
.ToArray ();
while (enums.All (e => e.MoveNext ())) {
yield return enums.Select (e => e.Current).ToArray ();
}
}
public static IEnumerable<TSource[]> Combine<TSource> (params IEnumerable<TSource>[] sources)
{
return sources.Combine ();
}
Would this work for you?
public static class Parallel
{
public static void ForEach<T>(IEnumerable<T>[] sources,
Action<T> action)
{
foreach (var enumerable in sources)
{
ThreadPool.QueueUserWorkItem(source => {
foreach (var item in (IEnumerable<T>)source)
action(item);
}, enumerable);
}
}
}
// sample usage:
static void Main()
{
string[] s1 = { "1", "2", "3" };
string[] s2 = { "4", "5", "6" };
IEnumerable<string>[] sources = { s1, s2 };
Parallel.ForEach(sources, s => Console.WriteLine(s));
Thread.Sleep(0); // allow background threads to work
}
For C# 2.0, you need to convert the lambda expressions above to delegates.
Note: This utility method uses background threads. You may want to modify it to use foreground threads, and probably you'll want to wait till all threads finish. If you do that, I suggest you create sources.Length - 1 threads, and use the current executing thread for the last (or first) source.
(I wish I could include waiting for threads to finish in my code, but I'm sorry that I don't know how to do that yet. I guess you should use a WaitHandle Thread.Join().)