Peta dan Kurangi di .NET

Jawaban:

298

Setara dengan Linq pada Map dan Reduce: Jika Anda cukup beruntung memiliki linq maka Anda tidak perlu menulis peta sendiri dan mengurangi fungsi. C # 3.5 dan Linq sudah memilikinya meskipun dengan nama yang berbeda.

  • Peta adalah Select:

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

    Enumerable.Range(1, 10).Aggregate(0, (acc, x) => acc + x);
  • Filter adalah Where:

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

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

Tony
sumber
1
Terjemahan itu benar tetapi melewatkan satu poin kunci. Langkah pengocokan dalam pengurangan peta sangat penting dalam pengurangan peta tetapi tidak muncul dalam nama seseorang tidak harus menulis kode apa pun untuk itu. Ini semata-mata didorong oleh Kunci yang diekstrak dalam langkah peta. Jawaban Joel Martinez menyoroti bahwa menurut saya lebih baik.
xtofs
2
Tautan tidak berfungsi, tautan yang benar adalah: justinshield.com/2011/06/mapreduce-in-c
Alexandru-Dan Pop
12
Mengapa oh mengapa tidak mereka hanya menyebutnya Reducebukan Aggregate... MS hanya suka programmer pemilik dapat mengganggu
John Henckel
13
@ JohnHenckel, saya jelas bukan sumber yang otoritatif, tapi saya cukup yakin ini berasal dari SQL. Saya percaya LINQ asli dibeli sebagai cara membuat berinteraksi dengan sql lebih mudah di C #. Ketika Anda memberi nama fungsi di dunia itu, agregat mulai terdengar sedikit lebih akrab daripada "mengurangi" bila dibandingkan dengan hal-hal seperti Select and Group By. Saya tidak mengatakan itu benar, itu mengganggu saya tanpa akhir tetapi saya membayangkan itulah alasannya.
Elliot Blackburn
18

Kelas-kelas masalah yang cocok untuk solusi gaya mapreduce adalah masalah agregasi. Mengekstrak data dari dataset. Di C #, orang bisa memanfaatkan LINQ untuk memprogram dalam gaya ini.

Dari artikel berikut: http://codecube.net/2009/02/mapreduce-in-c-using-linq/

metode GroupBy bertindak sebagai peta, sedangkan metode Pilih melakukan pekerjaan mengurangi hasil antara menjadi daftar hasil akhir.

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

Untuk bagian yang didistribusikan, Anda dapat memeriksa DryadLINQ: http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx

Joel Martinez
sumber
3

Karena saya tidak pernah dapat mengingat bahwa LINQ menyebutnya Where, Selectdan Aggregatebukannya Filter, Mapdan Reducekarenanya saya membuat beberapa metode ekstensi yang dapat Anda gunakan:

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

Berikut adalah 3 metode (dari 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);
}

Beberapa detail lebih lanjut dari https://github.com/cs-util-com/cscore#ienumerable-extensions :

masukkan deskripsi gambar di sini

CsUtil.com
sumber