虽然map是从对象列表中选择“列”的适当解决方案,但它也有缺点。如果没有明确检查列是否存在,它将抛出一个错误,并(最多)为您提供undefined。我会选择reduce解决方案,它可以简单地忽略该属性,甚至为您设置默认值。
function getFields(list, field) {
// reduce the provided list to an array only containing the requested field
return list.reduce(function(carry, item) {
// check if the item is actually an object and does contain the field
if (typeof item === 'object' && field in item) {
carry.push(item[field]);
}
// return the 'carry' (which is the list of matched field values)
return carry;
}, []);
}
jsbin示例
即使提供的列表中的某个项不是对象或不包含该字段,这也会起作用。
如果项不是对象或不包含字段,甚至可以通过协商默认值来使其更加灵活。
function getFields(list, field, otherwise) {
// reduce the provided list to an array containing either the requested field or the alternative value
return list.reduce(function(carry, item) {
// If item is an object and contains the field, add its value and the value of otherwise if not
carry.push(typeof item === 'object' && field in item ? item[field] : otherwise);
// return the 'carry' (which is the list of matched field values)
return carry;
}, []);
}
jsbin示例
这与map相同,因为返回的数组的长度与提供的数组相同。(在这种情况下,地图比缩减略便宜):
function getFields(list, field, otherwise) {
// map the provided list to an array containing either the requested field or the alternative value
return list.map(function(item) {
// If item is an object and contains the field, add its value and the value of otherwise if not
return typeof item === 'object' && field in item ? item[field] : otherwise;
}, []);
}
jsbin示例
还有一个最灵活的解决方案,它可以让你通过提供一个替代价值在两种行为之间切换。
function getFields(list, field, otherwise) {
// determine once whether or not to use the 'otherwise'
var alt = typeof otherwise !== 'undefined';
// reduce the provided list to an array only containing the requested field
return list.reduce(function(carry, item) {
// If item is an object and contains the field, add its value and the value of 'otherwise' if it was provided
if (typeof item === 'object' && field in item) {
carry.push(item[field]);
}
else if (alt) {
carry.push(otherwise);
}
// return the 'carry' (which is the list of matched field values)
return carry;
}, []);
}
jsbin示例
正如上面的示例(希望)揭示了这一工作方式,让我们通过使用Array.concat函数来稍微缩短该函数。
function getFields(list, field, otherwise) {
var alt = typeof otherwise !== 'undefined';
return list.reduce(function(carry, item) {
return carry.concat(typeof item === 'object' && field in item ? item[field] : (alt ? otherwise : []));
}, []);
}
jsbin示例