I've been trying to create a generic partition function that returns an array of arrays. the function should be made under the following guidelines:
Arguments:
Objectives:
Call <function> for each element in <array> passing it the arguments:
element, key, <array>
Return an array that is made up of 2 sub arrays:
0. An array that contains all the values for which <function> returned something truthy
1. An array that contains all the values for which <function> returned something falsy
Here is what I have so far. I get the return of two. I feel like maybe I just have to do the filter function on two separate occasions, but I'm not sure how to put it together. Thoughts and suggestions are highly appreciated.
_.partition = function (collection, test){
var allValues = [];
var matches = [];
var misMatches = [];
_.filter(collection.value, function(value, key, collection){
if (test(value[key], key, collection) === "string"){
matches.push(value[key]);
}else{
misMatches.push(value[key]);
}
});
return allValues.push(matches, misMatches);
}
Here is a version which uses reduce
:
function partition(arr, filter) {
return arr.reduce(
(r, e, i, a) => {
r[filter(e, i, a) ? 0 : 1].push(e);
return r;
}, [[], []]);
}
Here's an alternative version which uses Array#filter
to find the matches, and builds an array of non-matches as it goes along:
function partition(arr, filter) {
var fail = [];
var pass = arr.filter((e, i, a) => {
if (filter(e, i, a)) return true;
fail.push(e);
});
return [pass, fail];
}
And a typed TypeScript variant:
function partition<T>(arr: T[], filter: (el: T, i: number, a: T[]) => boolean) {
const fail: T[] = [];
const pass = arr.filter((e, i, a) => {
if (filter(e, i, a)) return true;
fail.push(e);
});
return [pass, fail];
}