Хоча 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
трохи дешевше, ніж а reduce
):
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
var foos = objArray.pluck("foo");
.