web-dev-qa-db-fra.com

Mapper et réduire en .NET

Quels scénarios justifieraient l’utilisation de l’algorithme " Carte et Réduire "?


Existe-t-il une implémentation .NET de cet algorithme?

126
Developer

Équivalents Linq de Map and Reduce: si vous avez la chance d’avoir linq, vous n’avez pas besoin d’écrire votre propre carte et de réduire les fonctions. C # 3.5 et Linq l’a déjà, bien que sous différents noms.

  • La carte est Select:

    Enumerable.Range(1, 10).Select(x => x + 2);
    
  • Réduire c'est Aggregate:

    Enumerable.Range(1, 10).Aggregate(0, (acc, x) => acc + x);
    
  • Le filtre est Where:

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

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

235
Tony

Les classes de problèmes bien adaptées à une solution de style mapreduce sont des problèmes d’agrégation. Extraire des données d'un jeu de données. En C #, on pourrait profiter de LINQ pour programmer dans ce style.

Extrait de l'article suivant: http://codecube.net/2009/02/mapreduce-in-c-using-linq/

la méthode GroupBy agit en tant que carte, tandis que la méthode Select permet de réduire les résultats intermédiaires dans la liste finale des résultats.

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

Pour la partie distribuée, vous pouvez consulter DryadLINQ: http://research.Microsoft.com/en-us/projects/dryadlinq/default.aspx

18
Joel Martinez

Puisque je ne me souviens jamais que LINQ l’appelle Where, Select et Aggregate à la place de Filter, Map et Reduce donc j'ai créé quelques méthodes d'extension que vous pouvez utiliser:

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

Voici les 3 méthodes (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);
}

Quelques détails supplémentaires de https://github.com/cs-util-com/cscore#ienumerable-extensions :

enter image description here

1
CsUtil.com

Si vous essayiez d'écrire votre propre version de Google, cela pourrait le justifier .. !!!

Sérieusement, si vous rencontrez un problème que vous pouvez décomposer en plusieurs problèmes plus petits, une solution Map-Réduire fonctionnerait. Le document Google sur MapReduce contient un certain nombre de bons exemples, notamment comment traiter des milliers de pages Web, compter le nombre de mots dans un document, etc.

0
Sean