Mapa y reducción en .NET

Respuestas:

298

Equivalentes de Linq de Map and Reduce: si tiene la suerte de tener linq, entonces no necesita escribir su propio mapa y reducir las funciones. C # 3.5 y Linq ya lo tiene aunque con diferentes nombres.

  • El mapa es Select:

    Enumerable.Range(1, 10).Select(x => x + 2);
  • Reducir es Aggregate:

    Enumerable.Range(1, 10).Aggregate(0, (acc, x) => acc + x);
  • El filtro es Where:

    Enumerable.Range(1, 10).Where(x => x % 2 == 0);

https://www.justinshield.com/2011/06/mapreduce-in-c/

Tony
fuente
1
La traducción es correcta pero se pierde un punto clave. El paso aleatorio en map reduce es crítico en map-reduce pero no aparece en el nombre y no es necesario escribir ningún código para ello. Se maneja únicamente por la clave que se extrae en el paso del mapa. La respuesta de Joel Martínez destaca que en mi opinión mejor.
xtofs
2
El enlace no funciona, el enlace correcto es: justinshield.com/2011/06/mapreduce-in-c
Alexandru-Dan Pop
12
¿Por qué ? ¿Por qué no simplemente lo llaman en Reducelugar de Aggregate... A MS le gusta molestar a los programadores?
John Henckel
13
@JohnHenckel, definitivamente no soy una fuente autorizada, pero estoy bastante seguro de que esto proviene de SQL. Creo que linq se compró originalmente como una forma de facilitar la interacción con sql en C #. Cuando nombra funciones en ese mundo, el agregado comienza a sonar un poco más familiar que "reducir" en comparación con cosas como Seleccionar y Agrupar por. No digo que sea correcto, me molesta sin fin, pero imagino que esa es la razón.
Elliot Blackburn
18

Las clases de problemas que son adecuadas para una solución de estilo mapreduce son problemas de agregación. De extraer datos de un conjunto de datos. En C #, uno podría aprovechar LINQ para programar en este estilo.

Del siguiente artículo: http://codecube.net/2009/02/mapreduce-in-c-using-linq/

el método GroupBy actúa como el mapa, mientras que el método Select hace el trabajo de reducir los resultados intermedios a la lista final de resultados.

var wordOccurrences = words
                .GroupBy(w => w)
                .Select(intermediate => new
                {
                    Word = intermediate.Key,
                    Frequency = intermediate.Sum(w => 1)
                })
                .Where(w => w.Frequency > 10)
                .OrderBy(w => w.Frequency);

Para la parte distribuida, puede consultar DryadLINQ: http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx

Joel Martinez
fuente
3

Ya que nunca puedo recordar que LINQ lo llama Where, Selecty Aggregateen lugar de Filter, Mapy Reducepor lo que he creado algunos métodos de extensión se puede utilizar:

IEnumerable<string> myStrings = new List<string>() { "1", "2", "3", "4", "5" };
IEnumerable<int> convertedToInts = myStrings.Map(s => int.Parse(s));
IEnumerable<int> filteredInts = convertedToInts.Filter(i => i <= 3); // Keep 1,2,3
int sumOfAllInts = filteredInts.Reduce((sum, i) => sum + i); // Sum up all ints
Assert.Equal(6, sumOfAllInts); // 1+2+3 is 6

Estos son los 3 métodos (de https://github.com/cs-util-com/cscore/blob/master/CsCore/PlainNetClassLib/src/Plugins/CsCore/com/csutil/collections/IEnumerableExtensions.cs ):

public static IEnumerable<R> Map<T, R>(this IEnumerable<T> self, Func<T, R> selector) {
    return self.Select(selector);
}

public static T Reduce<T>(this IEnumerable<T> self, Func<T, T, T> func) {
    return self.Aggregate(func);
}

public static IEnumerable<T> Filter<T>(this IEnumerable<T> self, Func<T, bool> predicate) {
    return self.Where(predicate);
}

Algunos detalles más de https://github.com/cs-util-com/cscore#ienumerable-extensions :

ingrese la descripción de la imagen aquí

CsUtil.com
fuente