一方で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の例
これは、提供されたリストの項目の1つがオブジェクトではないか、フィールドが含まれていない場合でも機能します。
アイテムがオブジェクトではない場合やフィールドが含まれていない場合にデフォルト値をネゴシエートすることで、より柔軟にすることもできます。
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の例
返される配列の長さは提供された配列と同じであるため、これはマップと同じです。(その場合、a map
はaより少し安いです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");
。