Skip to content

Instantly share code, notes, and snippets.

@samgiles
Created June 20, 2014 11:32
Show Gist options
  • Save samgiles/762ee337dff48623e729 to your computer and use it in GitHub Desktop.
Save samgiles/762ee337dff48623e729 to your computer and use it in GitHub Desktop.
Javascript flatMap implementation
// [B](f: (A) ⇒ [B]): [B] ; Although the types in the arrays aren't strict (:
Array.prototype.flatMap = function(lambda) {
return Array.prototype.concat.apply([], this.map(lambda));
};
@eldarshamukhamedov
Copy link

@AWilco +1. Note that writeable and enumerable both default to false, so you can leave those off.

@vojtechhabarta
Copy link

Same implementation as @dsacramone with added TypeScript type annotations.
Note that mapping function can also use index and original array.

function flatMap<T, U>(array: T[], callbackfn: (value: T, index: number, array: T[]) => U[]): U[] {
    return [].concat(...array.map(callbackfn));
}

@reverofevil
Copy link

Not mentioned is that you should never modify prototypes of default objects, which this code perfectly failed to do.

@leefsmp
Copy link

leefsmp commented Mar 6, 2017

If the stunt is performed by trained professionals that can be acceptable

@Ran-P
Copy link

Ran-P commented Mar 6, 2017

For optimization, don't use concat use : push.apply

@nick-bull
Copy link

@mischkl
Copy link

mischkl commented Jun 7, 2017

@ichpuchtli I like it, but isn't the order of the concatenation backwards?

@dsacramone gets my vote for most concise and readable, tho :)

@TrevorSayre
Copy link

TrevorSayre commented Jun 20, 2017

If you need to work with deeply nested arrays:

const myArray = [[1, 2],[3, [4, [5, 6]]], [7, [8, 9]]];

const flatMapDeep = (value, mapper) => {
  return Array.isArray(value) ?
    [].concat(...value.map(x => flatMapDeep(x, mapper))) :
    mapper(value);
}

const mapper = (x) => x * 11;
const flatArray = flatMapDeep(myArray, mapper); // [11, 22, 33, 44, 55, 66, 77, 88, 99]

@itrav
Copy link

itrav commented Mar 2, 2018

const flatMap = (a, f) => a.map(f).reduce((xs, ys) => [...xs, ...ys]); // using map first to avoid recursion in reduce

[1, 2, 3].map(x => [x, x + 1]);                                        // => [[1, 2], [2, 3], [3, 4]]

flatMap([1, 2, 3], x => [x, x + 1]);                                   // => [1, 2, 2, 3, 3, 4]

Copy link

ghost commented Feb 3, 2021

/*
recursive methods (at least obvious ones) are for chumps! lets do some string manipulation instead...  
works, assuming your array does not actually includes "[" or "]" characters ¯\(◉◡◔)/¯
*/

Array.prototype.cheeky_flatMap = function(){
  return JSON.parse( "[" 
                   + JSON.stringify(this)
                         .replace(/[\[\]\,]+/g,",")
                         .replace(/(^\,|\,$)/g,"")
                   + "]"
                   );
}

Also, works in any depth...
cheeky_flatmap([[1,2],[3,4],[[[5]]]]) - [1,2,3,4,5]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment