[英]Nested if statements - how to refactor conditions to use one if statement while iterating
我有一個對象數組:
var contacts = [
{
"firstName": "Akira",
"lastName": "Laine",
"number": "0543236543",
"likes": ["Pizza", "Coding", "Brownie Points"]
},
{
"firstName": "Harry",
"lastName": "Potter",
"number": "0994372684",
"likes": ["Hogwarts", "Magic", "Hagrid"]
},
{
"firstName": "Sherlock",
"lastName": "Holmes",
"number": "0487345643",
"likes": ["Intriguing Cases", "Violin"]
},
{
"firstName": "Kristian",
"lastName": "Vos",
"number": "unknown",
"likes": ["JavaScript", "Gaming", "Foxes"]
}
];
我寫了一個函數來遍歷它們。
function lookUpProfile(name, prop) {
for ( i = 0; i < contacts.length; i++) {
if (contacts[i].firstName === name) {
if (contacts[i].hasOwnProperty(prop)) {
return contacts[i][prop]
} else {
return "No such property";
}
}
}
return "No such contact";
}
console.log(lookUpProfile("Harry", "likes"));
我試圖重組該函數,因此可以使用一個if語句和AND運算符,而不是使用兩個嵌套的if語句。 我為什么這樣做以提高可讀性,因為我發現嵌套的ifs難以閱讀。 當我這樣做時,雖然我沒有得到期望的返回值-當對象確實存在時,我得到了“沒有這樣的屬性”。 那么換句話說,為什么第二個功能不能正常工作? 我是否破壞了函數迭代的方式?
function lookUpProfile(name, prop) {
for (var i = 0; i < contacts.length; i++) {
if (contacts[i].firstName === name && contacts[i].hasOwnProperty(prop)) {
return contacts[i][prop]
} else {
return "No such property";
}
}
return "No such contact";
}
console.log(lookUpProfile("Harry", "likes"));
這里的問題是您正在嘗試做兩件事。
為此,嵌套if
是有意義的。 2位邏輯,2 if
語句。
您當然可以將其重構為不使用嵌套的ifs,首先嘗試查找該對象,然后檢查該對象是否具有必需的屬性:
function lookUpProfile(name, prop) { var obj = contacts.find(c => c.firstName === name); if(!obj) return "No such contact"; if(obj.hasOwnProperty(prop)) return obj[prop]; return "No such property"; } var contacts = [ { "firstName": "Akira", "lastName": "Laine", "number": "0543236543", "likes": ["Pizza", "Coding", "Brownie Points"] }, { "firstName": "Harry", "lastName": "Potter", "number": "0994372684", "likes": ["Hogwarts", "Magic", "Hagrid"] }, { "firstName": "Sherlock", "lastName": "Holmes", "number": "0487345643", "likes": ["Intriguing Cases", "Violin"] }, { "firstName": "Kristian", "lastName": "Vos", "number": "unknown", "likes": ["JavaScript", "Gaming", "Foxes"] } ]; console.log(lookUpProfile("Harry", "likes")); console.log(lookUpProfile("Harry", "foo")); console.log(lookUpProfile("Bob", "likes"));
第二個功能無法正常工作,因為在這里:
for (var i = 0; i < contacts.length; i++) {
if (contacts[i].firstName === name && contacts[i].hasOwnProperty(prop)) {
return contacts[i][prop]
} else {
return "No such property";
}
}
如果第一個if失敗,則代碼return
。 因此,因為它返回,所以每當一個項目失敗時,如果沒有其他項目被處理,這與您的第一個函數不同。
如果要保持當前的for循環並僅返回聯系人是否存在(以及最終屬性),則可以跟蹤聯系人是否存在並相應地返回錯誤。
請注意,這可以用更短,更好的方式來實現,我只是想將您的代碼保持在當前狀態,而不要使用您不想使用的double if語句。
var contacts = [ { "firstName": "Akira", "lastName": "Laine", "number": "0543236543", "likes": ["Pizza", "Coding", "Brownie Points"] }, { "firstName": "Harry", "lastName": "Potter", "number": "0994372684", "likes": ["Hogwarts", "Magic", "Hagrid"] }, { "firstName": "Sherlock", "lastName": "Holmes", "number": "0487345643", "likes": ["Intriguing Cases", "Violin"] }, { "firstName": "Kristian", "lastName": "Vos", "number": "unknown", "likes": ["JavaScript", "Gaming", "Foxes"] } ]; function lookUpProfile(name, prop) { var contactExists = false; for (var i = 0; i < contacts.length; i++) { contactExists = contactExists || contacts[i].firstName === name; if (contactExists && contacts[i].hasOwnProperty(prop)) { return contacts[i][prop]; } } return contactExists ? "No such property" : "No such contact"; } console.log(lookUpProfile("Harry", "likes")); console.log(lookUpProfile("Akira", "S")); console.log(lookUpProfile("Nothing", "Hey"));
您的第二個代碼示例的問題是,無論您的if
語句中的條件計算結果如何,您都將始終從函數中return
,從而在第一次迭代后停止循環。
如果您不希望使用嵌套語句,則可以創建一個變量,該變量定義循環完成后將返回的消息(即:是否應返回"No such property"
或"No such contact"
)。 因此,您可以在循環內更改變量,以使其代表完成后將返回的內容,而不是從循環內返回。
例如:
function lookUpProfile(name, prop) {
let msg = "No such contact"; // default message
for (let i = 0; i < contacts.length; i++) {
let hasProp = contacts[i].hasOwnProperty(prop);
if (contacts[i].firstName === name && hasProp) {
return contacts[i][prop];
} else if(!hasProp) {
msg = "No such property"; // change the value of the message to return
}
}
return msg; // if we reach this point, we must've not returned earlier in the loop, so we can output the message
}
console.log(lookUpProfile("Harry", "likes"));
但是,通過使用嵌套的if
語句,您將允許您的代碼比上述代碼更早return
(即:不需要運行整個循環),從而使代碼更高效。
這是使用Array.find
的非常緊湊且易讀的代碼,使用的檢查次數與第一個實現中的檢查次數大致相同(簡化代碼以提高可讀性):
const arr = [ {name: 'john', age: 42}, {name: 'doe', age: 24}, ]; const lookup = (name, prop) => { let found = arr.find(elt => elt.name==name); if (!found) return 'No such name'; if (found && !found.hasOwnProperty(prop)) return 'No such property'; return found; } console.log( lookup('john', 'age'), lookup('john', 'size'), lookup('joe', 'age'), lookup('joe', 'size'), );
像這樣做。 您的代碼中的問題是,如果第一項不符合條件,您將立即返回。
function lookUpProfile(name, prop) {
for ( i = 0; i < contacts.length; i++) {
if (contacts[i].firstName === name && contacts[i].hasOwnProperty(prop)) {
return contacts[i][prop];
}
}
return "No such contact or property under contact";
}
函數/方法中的return
語句停止執行函數中的其余代碼。 返回方法-好的,我找到了預期的結果-這樣我的工作就完成了:)
function lookUpProfile(name, prop) {
var result = null;
for (var i = 0; i < contacts.length; i++) {
if (contacts[i].firstName === name && contacts[i].hasOwnProperty(prop)) {
return contacts[i][prop]
} else {
result = "No such property";
}
}
return result;
}
對於多個匹配:
function lookUpProfile(name, prop) {
var result = [];
for (var i = 0; i < contacts.length; i++) {
if (contacts[i].firstName === name && contacts[i].hasOwnProperty(prop)) {
result.push(contacts[i][prop]);
} else if(result == []) {
result = "No such property";
}
}
return result;
}
console.log(lookUpProfile("Harry", "likes"))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.