Vra

Ek skryf 'n paar uitbreidings aan die kaart na te boots en funksies te verminder in Lisp.

public delegate R ReduceFunction<T,R>(T t, R previous);
public delegate void TransformFunction<T>(T t, params object[] args);

public static R Reduce<T,R>(this List<T> list, ReduceFunction<T,R> r, R initial)
{
     var aggregate = initial;
     foreach(var t in list)
         aggregate = r(t,aggregate);

     return aggregate;
}
public static void Transform<T>(this List<T> list, TransformFunction<T> f, params object [] args)
{
    foreach(var t in list)
         f(t,args);
}

Die funksie transformeer sal kap op cruft soos:

foreach(var t in list)
    if(conditions && moreconditions)
        //do work etc

Maak dit sin? Kon dit beter wees?

Was dit nuttig?

Oplossing

Dit lyk baie soortgelyk aan uitbreidings in Linq reeds:

//takes a function that matches the Func<T,R> delegate
listInstance.Aggregate( 
    startingValue, 
    (x, y) => /* aggregate two subsequent values */ );

//takes a function that matches the Action<T> delegate
listInstance.ForEach( 
    x => /* do something with x */);

Hoekom is die 2de voorbeeld genoem transformeer? Het jy van plan is om die waardes in die lys op 'n manier te verander? As dit die geval is, kan jy beter daaraan toe wees met behulp van ConvertAll<T> of Select<T>.

Ander wenke

Volgens hierdie skakel funksionele programmering in C # 3,0: Hoe Map / Verminder / Filter kan jou wêreld Rock die volgende is die ekwivalent in C # onder die System.Linq naamruimte:

Ek wil gebruik maak van die gebou in Func afgevaardigdes plaas. Hierdie selfde kode sal werk op enige IEnumerable. Jou kode sal draai in:

public static R Reduce<T,R>(this IEnumerable<T> list, Func<T,R> r, R initial)
{
     var aggregate = initial;
     foreach(var t in list)
         aggregate = r(t,aggregate);

     return aggregate;
}
public static void Transform<T>(this IEnumerable<T> list, Func<T> f)
{
    foreach(var t in list)
             f(t);
}

Jy wil dalk 'n manier om 'n kaart te doen by te voeg, maar om terug te keer 'n nuwe lys, in plaas van die werk op die lys geslaag in (en die terugkeer van die lys kan nuttig wees om ketting bewys ander bedrywighede) ... miskien 'n oorlaaide weergawe met 'n Titel wat as jy wil 'n nuwe lys of nie terugkeer, as sodanig:

public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f,
        params object [] args)
{
    return Transform(list, f, false, args);
}

public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f,
        bool create, params object [] args)
{
    // Add code to create if create is true (sorry,
    // too lazy to actually code this up)
    foreach(var t in list)
         f(t,args);
    return list;
}

Ek sou aanbeveel om uitbreiding metodes wat intern gebruik linQ soos hierdie :

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

Hier 'n paar voorbeeld gebruike:

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

( https://github.com/cs-util-com / cscore # ienumerable-uitbreidings vir meer voorbeelde)

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top