【问题标题】:Map and Reduce in .NET.NET 中的映射和归约
【发布时间】:2010-09-30 12:54:38
【问题描述】:

哪些场景需要使用“Map and Reduce”算法?


这个算法有 .NET 实现吗?

【问题讨论】:

标签: c# mapreduce


【解决方案1】:

非常适合 mapreduce 样式解决方案的问题类别是聚合问题。从数据集中提取数据。在 C# 中,可以利用 LINQ 以这种风格进行编程。

来自以下文章: http://codecube.net/2009/02/mapreduce-in-c-using-linq/

GroupBy 方法充当地图,而 Select 方法将中间结果减少到最终结果列表中。

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

对于分布式部分,您可以查看 DryadLINQ:http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx

【讨论】:

    【解决方案2】:

    Map 和 Reduce 的 Linq 等价物: 如果你有幸拥有 linq,那么你就不需要编写自己的 map 和 reduce 函数。 C# 3.5 和 Linq 已经有了它,尽管名称不同。

    • 地图是Select:

      Enumerable.Range(1, 10).Select(x => x + 2);
      
    • 减少是Aggregate:

      Enumerable.Range(1, 10).Aggregate(0, (acc, x) => acc + x);
      
    • 过滤器是Where:

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

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

    【讨论】:

    • 翻译是正确的,但是漏掉了一个关键点。 map reduce 中的 shuffle 步骤在 map-reduce 中至关重要,但不会出现在名称中,因为不需要为它编写任何代码。它仅由在映射步骤中提取的 Key 驱动。 Joel Martinez 的回答在我看来更好地强调了这一点。
    • 链接失效,正确的链接是:justinshield.com/2011/06/mapreduce-in-c
    • 为什么哦,为什么他们不直接称它为Reduce 而不是Aggregate... MS 只是喜欢惹恼程序员
    • @JohnHenckel,我绝对不是权威来源,但我很确定这来自 SQL。我相信 linq 最初是作为一种在 C# 中更容易与 sql 交互的方式购买的。当您在那个世界中命名函数时,与 Select 和 Group By 之类的东西相比,聚合开始听起来比“减少”更熟悉一些。我并不是说这是对的,这让我很恼火,但我想这就是它的原因。
    • @ElliotBlackburn +1,但不仅如此,我很确定当 LINQ 首次引入时(2007 年),JavaScript 标准中没有“减少”这样的功能。 caniuse.com/?search=reduce 所以我们最好抱怨 JavaScript 的作者选择“减少”而不是“聚合”
    【解决方案3】:

    由于我不记得 LINQ 将其称为 WhereSelectAggregate 而不是 FilterMapMapReduce,所以我创建了一些您可以使用的扩展方法:

    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
    

    这里有 3 种方法(来自 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);
    }
    

    更多详情来自https://github.com/cs-util-com/cscore#ienumerable-extensions

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      • 2010-10-18
      • 2010-11-07
      • 1970-01-01
      相关资源
      最近更新 更多