multidimensional length array c# list

length - list string string c#



¿Cuál es la forma de Cid-idiomática para aplicar un operador en dos listas? (4)

Estoy acostumbrado a hacer esto (desde otros idiomas):

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

Esto toma dos listas de igual tamaño y aplica una función a sus miembros, uno a la vez, para obtener una lista de los resultados. Podría ser una función tan simple como la multiplicación (arriba) o algo más complejo:

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

Puedo pensar en algunas maneras diferentes de hacer esto en C #, pero no estoy seguro de cómo lo haría un programador capacitado en C #. ¿Cuál es la forma correcta de abordar esto en el mundo de C #?

(La única parte que pregunto es dónde c = f(a,b) . Estoy familiarizado con la creación de listas y el acceso a sus elementos).


Asumiendo .Net 3.5 con listas de igual longitud:

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);

Resultado:

5

2

6

Ejemplo de DotNetFiddle.Net


Para las versiones .NET sin LINQ, recomendaría un ciclo for para lograr esto:

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])); }

Esto supone, por supuesto, que las listas son del mismo tamaño y no cambian. Si conoce el tamaño de la lista con anticipación, también puede instanciarlo al tamaño correcto, luego simplemente configure el elemento durante el ciclo.


Si no está usando .NET 4.0, aquí está cómo escribir su propio método de extensión para hacer un 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); } } }


var c = a.Zip(b, (x, y) => x * y);

Para el más complejo después de su edición:

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

Tenga en cuenta que Zip es un método de extensión tanto de Enumerable que actúa en IEnumerable<T> como de Queryable que actúa en IQueryable<T> , por lo que es posible que, si la lambda es una con la que puede tratar un proveedor de consultas determinado, podría hacerlo. ser procesado como una consulta SQL en una base de datos, o de alguna otra manera que no sea en la memoria en .NET.

Alguien mencionó que esto era nuevo con 4.0 en los comentarios. No es difícil implementarlo por ti mismo 3.5:

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); } }

Para .NET2.0 o .NET3.0 puede tener lo mismo, pero no como un método de extensión, que responde a otra pregunta de los comentarios; no había realmente una forma idiomática de hacer tales cosas en .NET en ese momento, o al menos no con un consenso firme entre quienes codificamos en .NET en ese momento. Algunos de nosotros teníamos métodos como el anterior en nuestros kits de herramientas (aunque no en los métodos de extensión, obviamente), pero eso era más porque estábamos influenciados por otros lenguajes y bibliotecas que por cualquier otra cosa (por ejemplo, estaba haciendo cosas como las anteriores por cosas que sabía de El STL de C ++, pero esa no era la única fuente de inspiración posible)