编辑:
下面是 lodash 在纯 JavaScript 中的 partition 方法的实现,在 JSDoc 中带有 TypeScript 类型。它使用Array.prototype.reduce。正如 JSDoc 注释所说,此分区函数执行以下操作:
返回一个数组,索引处有两个数组
0 和 1。索引 0 处的数组是所有项目
在arr 中通过了predicate 真值测试
返回一个真实的值。索引 1 处的数组是所有项目
在arr 中,通过返回未通过predicate 真值测试
一个虚假的值。
// ----- partition function declaration -----
/** Returns an array with two arrays at index
* 0 and 1. The array at index 0 is all the items
* in `arr` that passed the `predicate` truth test by
* returning a truthy value. The array at index 1 is all the items
* in `arr` that failed the `predicate` truth test by returning
* a falsy value.
* @template {any} T
* @param {Array<T>} arr
* @param {(el:T, index:number, arr:Array<T>) => any} predicate
* @returns {[Array<T>, Array<T>]}
*/
function partition(arr, predicate) {
return arr.reduce(
// this callback will be called for each element of arr
function(partitionsAccumulator, arrElement, i, arr) {
if (predicate(arrElement, i, arr)) {
// predicate passed push to left array
partitionsAccumulator[0].push(arrElement);
} else {
// predicate failed push to right array
partitionsAccumulator[1].push(arrElement);
}
// whatever is returned from reduce will become the new value of the
// first parameter of the reduce callback in this case
// partitionsAccumulator variable if there are no more elements
// this return value will be the return value of the full reduce
// function.
return partitionsAccumulator;
},
// the initial value of partitionsAccumulator in the callback function above
// if the arr is empty this will be the return value of the reduce
[[], []]
);
}
// ----- function usage examples -----
// This partition gets all numbers which are even in the
// first array (all these numbers returned true for the predicate)
// and returns all numbers which are odd in the second array
var res = partition([1, 2, 3], function(number) {
return number % 2 === 0;
});
console.log(res); // → [[2], [1, 3]]
// This partition gets all indexes that are more than half
// way through the array.
res = partition([1, 2, 3, 4], function(number, index, array) {
return index > Math.floor(array.length / 2) - 1;
});
console.log(res); // → [[3, 4], [1, 2]]
// This partition gets all strings with length greater than 4
res = partition(["bam!", "kazaam!", "blam!", "wam!", "jam!"], (string) => {
return string.length > 4;
});
console.log(res); // → [["kazaam!", "blam!"], ["bam!", "wam!", "jam!"]]
使用 JSDoc 类型的好处是,如果您有像 VSCode 这样的编辑器,当您在 mac 上按 command 或在 windows 上按 ctrl 时,它会向您显示类型和描述。看起来像这样:
鉴于我在 JSDoc 注释中使用了模板 T,VSCode 足够聪明,因为这张图片中参数 1 中的数组充满了数字,所以 T 是一个数字。如果您传入一个字符串数组,它将正确提示谓词的el 参数的类型以及内部数组的返回项值作为字符串,因为它们也使用模板T。
原答案
如果您还没有使用库,讨厌启动它们,但 lodash 有一个功能正是这样做的,称为 partition。
_.partition([1, 2, 3], function(n) {
return n % 2;
});
// → [[1, 3], [2]]
_.partition([1.2, 2.3, 3.4], function(n) {
return this.floor(n) % 2;
}, Math);
// → [[1.2, 3.4], [2.3]]
创建一个元素数组,分成两组,第一组
包含元素谓词返回truthy for,而第二个
其中包含元素谓词返回错误。谓词是
绑定到 thisArg 并使用三个参数调用:(value, index|key,
收藏)。
如果为谓词提供了属性名称,则创建的 _.property
style 回调返回给定元素的属性值。
如果还为 thisArg 提供了值,则创建的 _.matchesProperty
对于具有匹配属性的元素,样式回调返回 true
值,否则为假。
如果为谓词提供了一个对象,则创建的 _.matches 样式
对于具有以下属性的元素,回调返回 true
给定对象,否则为假。参数
- collection (Array|Object|string):要迭代的集合。
- [predicate=_.identity] (Function|Object|string):每次迭代调用的函数。
- [thisArg] (*):谓词的 this 绑定。
返回
(Array):返回分组元素的数组。
更多示例
var users = [
{ 'user': 'barney', 'age': 36, 'active': false },
{ 'user': 'fred', 'age': 40, 'active': true },
{ 'user': 'pebbles', 'age': 1, 'active': false }
];
var mapper = function(array) {
return _.pluck(array, 'user');
};
// using the `_.matches` callback shorthand
_.map(_.partition(users, { 'age': 1, 'active': false }), mapper);
// → [['pebbles'], ['barney', 'fred']]
// using the `_.matchesProperty` callback shorthand
_.map(_.partition(users, 'active', false), mapper);
// → [['barney', 'pebbles'], ['fred']]
// using the `_.property` callback shorthand
_.map(_.partition(users, 'active'), mapper);
// → [['fred'], ['barney', 'pebbles']]