For me the canonical way of learning about map and reduce is to
foldl
map
Now in JavaScript this isn't terribly efficient …
const personArray = [ { name: 'Swastik', age: 23 }, { name: 'John', age: 42 }, { name: 'Rock', age: 45 }, ]; type Person = typeof personArray[number]; // reduce function foldl<X, Y>(fn: (y: Y, x: X) => Y, to: Y, from: X[]): Y { return from.length < 1 ? to : foldl(fn, fn(to, from[0]), from.slice(1)); } function map<X, Y>(fn: (x: X) => Y, from: X[]): Y[] { const append: (ys: Y[], x: X) => Y[] = (ys, x) => { ys.push(fn(x)); return ys; }; return foldl(append, [], from); } function rmap<X, Y>(fn: (x: X) => Y, from: X[]): Y[] { // return from.length < 1 ? // [] : // [fn(from[0]), ...rmap(fn, from.slice(1))]; // if (from.length < 1) return []; const rest = rmap(fn, from.slice(1)); rest.unshift(fn(from[0])); return rest; } function filter<X>(fn: (x: X) => boolean, from: X[]): X[] { const appendAccept: (xs: X[], x: X) => X[] = (xs, x) => { if (fn(x)) xs.push(x); return xs; }; return foldl(appendAccept, [], from); } function rfilter<X>(fn: (x: X) => boolean, from: X[]): X[] { // return from.length < 1 ? // [] : // fn(from[0]) ? // [from[0], ...rfilter(fn, from.slice(1))] : // rfilter(fn, from.slice(1)); // if (from.length < 1) return []; const rest = rfilter(fn, from.slice(1)); if (fn(from[0])) rest.unshift(from[0]); return rest; } type People = { [name: string]: number; }; const appendPerson: (a: People, p: Person) => People = (people, person) => { people[person.name] = person.age; return people; }; console.log(foldl(appendPerson, {}, personArray)); const extractName: (p: Person) => string = (person) => person.name; console.log(map(extractName, personArray)); console.log(rmap(extractName, personArray)); const inUpperAlphabet: (p: Person) => boolean = (person) => person.name[0].toLowerCase() > 'm'; console.log(filter(inUpperAlphabet, personArray)); console.log(rfilter(inUpperAlphabet, personArray));
This transpiles down to
const personArray = [ { name: 'Swastik', age: 23 }, { name: 'John', age: 42 }, { name: 'Rock', age: 45 }, ]; // reduce function foldl(fn, to, from) { return from.length < 1 ? to : foldl(fn, fn(to, from[0]), from.slice(1)); } function map(fn, from) { const append = (ys, x) => { ys.push(fn(x)); return ys; }; return foldl(append, [], from); } function rmap(fn, from) { if (from.length < 1) return []; const rest = rmap(fn, from.slice(1)); rest.unshift(fn(from[0])); return rest; } function filter(fn, from) { const appendAccept = (xs, x) => { if (fn(x)) xs.push(x); return xs; }; return foldl(appendAccept, [], from); } function rfilter(fn, from) { if (from.length < 1) return []; const rest = rfilter(fn, from.slice(1)); if (fn(from[0])) rest.unshift(from[0]); return rest; } const appendPerson = (people, person) => { people[person.name] = person.age; return people; }; console.log(foldl(appendPerson, {}, personArray)); const extractName = (person) => person.name; console.log(map(extractName, personArray)); console.log(rmap(extractName, personArray)); const inUpperAlphabet = (person) => person.name[0].toLowerCase() > 'm'; console.log(filter(inUpperAlphabet, personArray)); console.log(rfilter(inUpperAlphabet, personArray));
Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink.
Hide child comments as well
Confirm
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
For me the canonical way of learning about map and reduce is to
foldl
(reduce) using recursionmap
in terms offoldl
Now in JavaScript this isn't terribly efficient …
This transpiles down to