簡體   English   中英

嵌套的if語句-如何在迭代時重構條件以使用一個if語句

[英]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")); 

這里的問題是您正在嘗試做兩件事。

  1. 通過名字從數組中找到合適的對象。
  2. 確定該對象是否具有特定的屬性,如果是,則返回其值。

為此,嵌套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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM