Javascript Underline.js 513;.map函数:跳过一个值
我试图对一个对象数组使用underline.jsJavascript Underline.js 513;.map函数:跳过一个值,javascript,underscore.js,Javascript,Underscore.js,我试图对一个对象数组使用underline.js\uu.map函数,以获得一个包含每个对象属性的数组。这是通常的情况,因此: var finalArray = _.map(myArray, function(obj) { return obj.myProperty; }); 但在某些情况下,我需要在数组中不添加任何内容。可能是这样的: var finalArray = _.map(myArray, function(obj) { if (!obj.ignore) {
\uu.map
函数,以获得一个包含每个对象属性的数组。这是通常的情况,因此:
var finalArray = _.map(myArray, function(obj) {
return obj.myProperty;
});
但在某些情况下,我需要在数组中不添加任何内容。可能是这样的:
var finalArray = _.map(myArray, function(obj) {
if (!obj.ignore) {
return obj.myProperty;
}
});
这样做的结果是将未定义的值推送到数组中,这与根本不推送任何内容不同
map函数有没有办法不推送值,或者我是否需要对我的finalArray
进行后期处理以删除不需要的未定义的。您应该在\u.map()之前使用.filter()
这意味着您需要过滤,然后映射数组。
要以下划线方式执行此操作,您需要将数组传递到此管道:
myArray-->过滤器-->映射-->finalArray
.map
将新值映射到数组,您可以使用.filter
筛选数组。仅供参考,您可以使用.pull
从对象映射属性:
_.chain(myArray).filter(function(obj) { return !obj.ignore; }).pluck('myProperty').value();
您也可以像这样使用。其中
:
_.chain(myArray).where({ignore: false}).pluck('myProperty').value();
或:
您可以使用reduce:
myArray.reduce(function (acc, obj) {
if (!obj.ignore) {
acc.push(obj.myProperty);
}
return acc;
}, []);
或使用lodash:
_.reduce(myArray, function (acc, obj) {
if (!obj.ignore) {
acc.push(obj.myProperty);
}
return acc;
}, []);
这可以单独使用下划线方法完成:
还有一种方法。这个函数使用下划线中的compose函数。为什么要作曲?作曲以数学中的范畴理论为后盾。这种方式也是无点的
var pluckMyProp = function(array) {
return _.pluck(array, 'myProperty')
}
var reject = function(array) {
return _.reject(array, function(element) {
return element['ignore'] === true
})
}
var finalArray = _.compose(pluckMyProp, reject)
var data = [{myProperty: 1, ignore: false}, {ignore: true}, {myProperty: 2}]
finalArray(data) //=> [1,2]
尝试使用lodash的compact()
。它创建一个数组,删除所有虚假值。因此,值false
,null
,0
,“
,未定义的
和NaN
被删除
我正在使用它,它非常干净。在foucdeg描述他的问题之后,而不是之前,没有必要转换输入来决定是否应该排除它们。就性能而言,“之前筛选”会更好。您也可以将takeProperty
替换为。函数如另一个答案中所建议的@dev null。@foucdeg下划线使您以更小的单位思考,而不是一个包含多个作业的胖函数。我们鼓励您编写小的函数单元,将它们加入到顺序操作中,以形成更大的处理单元。我喜欢这种方法。它简单明了,可读性很强。(也是纯粹的功能性、一元思维)@Pavlo您需要一个带有下划线的显式.chain
,您可以简单地使用.reject('ignore')
而不是.reject(uu.property('ignore'))
。我认为这是最好的答案,因为它只在所有元素中循环一次,正如@foucdeg所问的“是否有一种方法让map函数不推送值”。答案是使用reduce()而不是map()。同意这应该是接受的答案-循环只有一次。还请注意,这适用于下划线js
,不确定为什么这里提到lodash
,因为OP询问下划线js
。下划线的DOC也有点混淆:“将一个值列表归结为一个单一的值。”在这种情况下,单个值是一个数组……我认为你应该考虑选择Thomas Eschemann的最佳答案,因为它按数组中的所有元素循环一次。“map函数是否有办法不推送值”,这是这个问题的主要目标。答案是使用reduce()而不是map()。当前选择的答案是问题的第二部分“我是否需要对finalArray进行后期处理以删除不需要的未定义值?”?第二部分的答案是:不,你不需要对finalArray()进行后期处理,你需要使用reduce()而不是map()来避免后期处理。要将上述内容从下划线转换为lodash,请将。
myArray.reduce(function (acc, obj) {
if (!obj.ignore) {
acc.push(obj.myProperty);
}
return acc;
}, []);
_.reduce(myArray, function (acc, obj) {
if (!obj.ignore) {
acc.push(obj.myProperty);
}
return acc;
}, []);
var finalArray = _.chain(myArray)
.reject('ignore')
.pluck('myProperty')
.value();
var pluckMyProp = function(array) {
return _.pluck(array, 'myProperty')
}
var reject = function(array) {
return _.reject(array, function(element) {
return element['ignore'] === true
})
}
var finalArray = _.compose(pluckMyProp, reject)
var data = [{myProperty: 1, ignore: false}, {ignore: true}, {myProperty: 2}]
finalArray(data) //=> [1,2]