Meskipun map
merupakan solusi yang tepat untuk memilih 'kolom' dari daftar objek, ia memiliki kelemahan. Jika tidak secara eksplisit memeriksa apakah ada kolom atau tidak, itu akan menimbulkan kesalahan dan (paling-paling) memberi Anda undefined
. Saya akan memilih reduce
solusi, yang dapat mengabaikan properti atau bahkan mengatur Anda dengan nilai default.
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;
}, []);
}
contoh jsbin
Ini akan berfungsi bahkan jika salah satu item dalam daftar yang disediakan bukan objek atau tidak mengandung bidang.
Ia bahkan dapat dibuat lebih fleksibel dengan menegosiasikan nilai default jika suatu item tidak menjadi objek atau tidak mengandung bidang.
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;
}, []);
}
contoh jsbin
Ini akan sama dengan peta, karena panjang array yang dikembalikan akan sama dengan array yang disediakan. (Dalam hal ini a map
sedikit lebih murah daripada 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;
}, []);
}
contoh jsbin
Dan kemudian ada solusi yang paling fleksibel, yang memungkinkan Anda beralih di antara kedua perilaku hanya dengan memberikan nilai alternatif.
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;
}, []);
}
contoh jsbin
Seperti contoh di atas (semoga) menjelaskan cara kerjanya, mari kita persingkat sedikit fungsinya dengan memanfaatkan Array.concat
fungsinya.
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 : []));
}, []);
}
contoh jsbin
var foos = objArray.pluck("foo");
.