ในขณะที่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");
ได้