Are there any languages that support foreach over multiple lists at once? Something like this:
foreach (string a in names, string b in places, string c in colors) {
// do stuff with a, b, c
}
Sure, this can be done with a regular for loop:
for (int n = 0; n<max, n++) {
a = names[n]; b = places[n]; c = colors[n];
}
but this loses the abstraction of foreach.
My meager google-fu only reveals people asking how to do multi-foreach in various languages that don’t support it. I’m guessing that some language uses it, I just can’t figure out which one.
2
Sure, Python can do that:
for a, b, c in zip(names, places, colors):
pass
zip
builds a list of tuples from the iterables passed to it. Python’s for
loop supports “unpacking”, that is to say the tuples are split into their components. It’s a weak form of pattern matching.
1
-
In C#, you can transform multiple collections into one collection of tuples, then use a
foreach
. There is no specific language syntax, but .NET Framework still allows you to do it. -
In SQL, you can use
join
. I’m not sure if the “languages” you’re looking for extend to SQL.
Note that in all cases, there is an ambiguity with your simple. What if colors.length < places.length
? If places.length > names.length
, would the remaining places be simply discarded?
Example for C#:
public static void Main(string[] args)
{
var names = new[] { "John", "Bill", "Joel" };
var places = new[] { 1, 2, 3 };
var colors = new[] { Color.AliceBlue, Color.BlueViolet, Color.DarkMagenta };
var zip = names.Zip(places, (n, p) => new { n, p }).Zip(colors, (t, c) => new { Name = t.n, Place = t.p, Color = c });
foreach (var z in zip)
{
Console.WriteLine(string.Join(", ", new[] { (object)z.Name, z.Place, z.Color }));
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true);
}
Or, using an extension method:
public static IEnumerable<Tuple<T1, T2, T3>> ZipSeveral<T1, T2, T3>(this IEnumerable<T1> first, IEnumerable<T2> second, IEnumerable<T3> third)
{
return first.Zip(second, (a, b) => new { a, b }).Zip(third, (t, c) => Tuple.Create(t.a, t.b, c));
}
you can reduce the code to a simple foreach
:
foreach (var z in names.ZipSeveral(places, colors))
{
Console.WriteLine(string.Join(", ", new[] { (object)z.Item1, z.Item2, z.Item3 }));
}
0