What is the C # idiomatic way of using an operator in two lists?

I'm used to doing this (from other languages):

a = 1, 2, 3; b = 5, 1, 2; c = a * b; // c = 5, 2, 6 

This takes two lists of equal size and applies the function to its members, one at a time, to get a list of results. It can be a function, simple as a multiplication (above) or something more complex:

  c = b>a ? ba : 0; // c = 4, 0, 0 

I can come up with several different ways to do this in C #, but I'm not sure how a C # -installed programmer would do it. What is the right way to do this in the C # world?

(The only part I ask is where c = f(a,b) . I am familiar with creating lists and accessing their elements.)

+61
list c #
Jun 03 '14 at 23:26
source share
4 answers
 var c = a.Zip(b, (x, y) => x * y); 

For more complicated after editing:

 var c = a.Zip(b, (x, y) => x > y ? x - y : 0); 

Note that Zip is an extension method from Enumerable that acts on IEnumerable<T> and Queryable that acts on IQueryable<T> , so it’s possible that if the lambda is the one the data provider can deal with, it can be processed like an SQL query in a database or some other way than the built-in memory in .NET.

Someone mentioned that it was new with 4.0 in the comments. It is not difficult to implement for 3.5 yourself:

 public class MyExtraLinqyStuff { public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector) { //Do null checks immediately; if(first == null) throw new ArgumentNullException("first"); if(second == null) throw new ArgumentNullException("second"); if(resultSelector == null) throw new ArgumentNullException("resultSelector"); return DoZip(first, second, resultSelector); } private static IEnumerable<TResult> DoZip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector) { using(var enF = first.GetEnumerator()) using(var enS = second.GetEnumerator()) while(enF.MoveNext() && enS.MoveNext()) yield return resultSelector(enF.Current, enS.Current); } } 

For .NET2.0 or .NET3.0 you can have the same thing, but not as an extension method, which answers another question from the comments; at that time there was no idiomatic way to do such things in .NET, or at least not with strong consensus among those we coded in .NET. Some of us had methods similar to the ones described above in our toolkits (although not extension methods), but this was all the more so since we were influenced by other languages ​​and libraries than anything else (for example, I did things like above, due to what I knew from C ++ STL, but that was hardly the only possible source of inspiration)

+77
Jun 03 '14 at 23:29
source share

Assuming .Net 3.5 with lists of equal length:

 var a = new List<int>() { 1, 2, 3 }; var b = new List<int>() { 5, 1, 2 }; var c = a.Select((x, i) => b[i] * x); 

Result:

5

2

6

DotNetFiddle.Net example

+23
Jun 03 '14 at 23:41
source share

If you're not using .NET 4.0, here's how to write your own extension method to make Zip.

 static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector) { using (IEnumerator<TFirst> e1 = first.GetEnumerator()) using (IEnumerator<TSecond> e2 = second.GetEnumerator()) { while (e1.MoveNext() && e2.MoveNext()) { yield return resultSelector(e1.Current, e2.Current); } } } 
+19
Jun 03 '14 at 23:36
source share

For .NET versions without LINQ, I would recommend a for loop to accomplish this:

 List<int> list1 = new List<int>(){4,7,9}; List<int> list2 = new List<int>(){11,2,3}; List<int> newList = new List<int>(); for (int i = 0; i < list1.Count; ++i) { newList.Add(Math.Max(list1[i], list2[i])); } 

This assumes that, of course, the lists are the same size and do not change. If you know the size of the list ahead of time, you can also create it in the correct size, and then just set the element during the loop.

+12
Jun 03 '14 at 23:37
source share



All Articles