Ánh xạ và thu nhỏ trong .NET


Câu trả lời:


298

Linq tương đương với Bản đồ và Thu nhỏ: Nếu bạn đủ may mắn để có linq thì bạn không cần phải viết bản đồ của riêng mình và giảm các chức năng. C # 3.5 và Linq đã có nó mặc dù dưới các tên khác nhau.

  • Bản đồ là Select:

    Enumerable.Range(1, 10).Select(x => x + 2);
  • Giảm là Aggregate:

    Enumerable.Range(1, 10).Aggregate(0, (acc, x) => acc + x);
  • Bộ lọc là Where:

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

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


1
Bản dịch là chính xác nhưng nó bỏ lỡ một điểm quan trọng. Bước xáo trộn trong giảm bản đồ là rất quan trọng trong thu nhỏ bản đồ nhưng không hiển thị trong tên mà người ta không phải viết bất kỳ mã nào cho nó. Nó chỉ được điều khiển bởi Khóa được trích xuất trong bước bản đồ. Joel Martinez trả lời nổi bật rằng theo tôi tốt hơn.
xtofs

2
Liên kết không hoạt động, liên kết chính xác là: justinshield.com/2011/06/mapreduce-in-c
Alexandru-Dan Pop

12
Tại sao oh tại sao họ không gọi nó Reducethay vì Aggregate... MS chỉ thích làm phiền các lập trình viên
John Henckel

13
@JohnHenckel, tôi chắc chắn không phải là một nguồn có thẩm quyền, nhưng tôi khá chắc chắn điều này đến từ SQL. Tôi tin rằng linq ban đầu được mua theo cách giúp tương tác với sql dễ dàng hơn trong C #. Khi bạn đặt tên các chức năng trong thế giới đó, tổng hợp bắt đầu nghe có vẻ quen thuộc hơn một chút so với "giảm" khi so sánh với những thứ như Chọn và Nhóm theo. Tôi không nói nó đúng, nó làm tôi khó chịu nhưng tôi tưởng tượng đó là lý do của nó.
Elliot Blackburn

18

Các lớp vấn đề rất phù hợp cho giải pháp kiểu mapreduce là các vấn đề tổng hợp. Trích xuất dữ liệu từ một tập dữ liệu. Trong C #, người ta có thể tận dụng LINQ để lập trình theo phong cách này.

Từ bài viết sau: http://codecube.net/2009/02/mapreduce-in-c-USE-linq/

phương thức GroupBy đóng vai trò là bản đồ, trong khi phương thức Chọn thực hiện công việc giảm kết quả trung gian vào danh sách kết quả cuối cùng.

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

Đối với phần được phân phối, bạn có thể kiểm tra DryadLINEQ: http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx


3

Vì tôi không bao giờ có thể nhớ rằng LINQ gọi nó Where, SelectAggregatethay vì Filter, MapReducevì vậy tôi đã tạo ra một vài phương thức mở rộng mà bạn có thể sử dụng:

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

Dưới đây là 3 phương thức (từ 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);
}

Một số chi tiết khác từ https://github.com/cs-util-com/cscore#ienumerable-extensions :

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.