如何在 javascript 中创建配分函数。使用以下准则
How to create a partition function in javascript. using the following guidelines
我一直在尝试创建一个 return 是数组数组的通用分区函数。该功能应根据以下准则进行:
参数:
- 一个数组
- 一个函数
目标:
为 中的每个元素调用 并将参数传递给它:
element, key, <array>
Return 由 2 个子数组组成的数组:
0。一个包含所有值的数组, returned something truthy
1. 包含 returned something falsy
的所有值的数组
这是我目前所拥有的。我得到两个 return。我觉得也许我只需要在两个不同的场合执行过滤功能,但我不确定如何将它们放在一起。非常感谢您的想法和建议。
_.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);
}
关于在不同场合调用 filter
方法的说法是正确的。一次 filter
调用将获得真值;另一个将获得虚假值:
_.partition = function(collection, testFunc) {
var matches = collection.filter(function(elem) {
return test(elem) === 'string';
});
var misMatches = collection.filter(function(elem) {
return test(elem) !== 'string';
});
return [matches, misMatches];
}
你很接近,但我发现有几个问题:
- 您返回的是
allValues.push
的结果 而不是 allValues
本身,而是数组的新长度。
- 您正在使用
_.filter
遍历数组元素并将它们排序到两个数组中。这很奇怪,因为它不是 _.filter
. 的预期用途
如果您想要使用 _.filter
的快速且可读的解决方案,这将有效:
_.mixin({
partition: function(collection, test) {
return [
_.filter(collection, test), // items which satisfy condition
_.filter(collection, _.negate(test)) // items which don't
];
}
});
下面是一个更有效的解决方案,它只对集合进行一次传递(这几乎是您已经拥有的):
_.mixin({
partition: function(collection, test) {
var matches = [], misMatches = [], value;
// can replace this loop with _.each
for (var i = 0, len = collection.length; i < len; ++i) {
value = collection[i];
// push the value into the appropriate array
if (test(value, i, collection)) {
matches.push(value);
} else {
misMatches.push(value);
}
}
return [matches, misMatches];
}
});
用法示例(和Plunker):
function isOdd(x) {
return x % 2;
}
// _.mixin allows you to do either one of these
_.partition([1, 2, 3, 4, 5, 6], isOdd); // result: [[1, 3, 5], [2, 4, 6]]
_([1, 2, 3, 4, 5, 6]).partition(isOdd); // result: [[1, 3, 5], [2, 4, 6]]
// this is a use case you brought up in the comments
_.partition([1, "a", 2, "b", 3, "c"], _.isString); // result: [["a", "b", "c"], [1, 2, 3]]
这是一个使用 reduce
的版本:
function partition(arr, filter) {
return arr.reduce(
(r, e, i, a) => {
r[filter(e, i, a) ? 0 : 1].push(e);
return r;
}, [[], []]);
}
这是一个替代版本,它使用 Array#filter
来查找匹配项,并构建一个 non-matches 的数组:
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];
}
这在函数式语言中通常称为 partition
ing。您将数组 (xs
) 和谓词函数 (p
) 提供给初始值为 [[],[]]
.
的 reduce
ing 函数
var partition = (xs,p) => xs.reduce( (r,e) => ( p(e) ? r[0].push(e)
: r[1].push(e)
, r
)
, [[],[]]
);
这样;
> partition([1,2,3,4,5,6,7,8,9,0], x => x < 5)
> [[1, 2, 3, 4, 0],[5, 6, 7, 8, 9]]
我一直在尝试创建一个 return 是数组数组的通用分区函数。该功能应根据以下准则进行:
参数:
- 一个数组
- 一个函数
目标:
为
中的每个元素调用 并将参数传递给它: element, key, <array>
Return 由 2 个子数组组成的数组:
0。一个包含所有值的数组,
returned something truthy
1. 包含returned something falsy 的所有值的数组
这是我目前所拥有的。我得到两个 return。我觉得也许我只需要在两个不同的场合执行过滤功能,但我不确定如何将它们放在一起。非常感谢您的想法和建议。
_.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);
}
关于在不同场合调用 filter
方法的说法是正确的。一次 filter
调用将获得真值;另一个将获得虚假值:
_.partition = function(collection, testFunc) {
var matches = collection.filter(function(elem) {
return test(elem) === 'string';
});
var misMatches = collection.filter(function(elem) {
return test(elem) !== 'string';
});
return [matches, misMatches];
}
你很接近,但我发现有几个问题:
- 您返回的是
allValues.push
的结果 而不是allValues
本身,而是数组的新长度。 - 您正在使用
_.filter
遍历数组元素并将它们排序到两个数组中。这很奇怪,因为它不是_.filter
. 的预期用途
如果您想要使用 _.filter
的快速且可读的解决方案,这将有效:
_.mixin({
partition: function(collection, test) {
return [
_.filter(collection, test), // items which satisfy condition
_.filter(collection, _.negate(test)) // items which don't
];
}
});
下面是一个更有效的解决方案,它只对集合进行一次传递(这几乎是您已经拥有的):
_.mixin({
partition: function(collection, test) {
var matches = [], misMatches = [], value;
// can replace this loop with _.each
for (var i = 0, len = collection.length; i < len; ++i) {
value = collection[i];
// push the value into the appropriate array
if (test(value, i, collection)) {
matches.push(value);
} else {
misMatches.push(value);
}
}
return [matches, misMatches];
}
});
用法示例(和Plunker):
function isOdd(x) {
return x % 2;
}
// _.mixin allows you to do either one of these
_.partition([1, 2, 3, 4, 5, 6], isOdd); // result: [[1, 3, 5], [2, 4, 6]]
_([1, 2, 3, 4, 5, 6]).partition(isOdd); // result: [[1, 3, 5], [2, 4, 6]]
// this is a use case you brought up in the comments
_.partition([1, "a", 2, "b", 3, "c"], _.isString); // result: [["a", "b", "c"], [1, 2, 3]]
这是一个使用 reduce
的版本:
function partition(arr, filter) {
return arr.reduce(
(r, e, i, a) => {
r[filter(e, i, a) ? 0 : 1].push(e);
return r;
}, [[], []]);
}
这是一个替代版本,它使用 Array#filter
来查找匹配项,并构建一个 non-matches 的数组:
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];
}
这在函数式语言中通常称为 partition
ing。您将数组 (xs
) 和谓词函数 (p
) 提供给初始值为 [[],[]]
.
reduce
ing 函数
var partition = (xs,p) => xs.reduce( (r,e) => ( p(e) ? r[0].push(e)
: r[1].push(e)
, r
)
, [[],[]]
);
这样;
> partition([1,2,3,4,5,6,7,8,9,0], x => x < 5)
> [[1, 2, 3, 4, 0],[5, 6, 7, 8, 9]]