嵌套的if语句-如何在迭代时重构条件以使用一个if语句

时间:2019-07-05 13:16:01

标签: javascript

我有一个对象数组:

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")); 

6 个答案:

答案 0 :(得分:3)

这里的问题是您正在尝试做两件事。

  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")); 

答案 1 :(得分:1)

第二个功能无法正常工作,因为:

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"));

答案 2 :(得分:1)

您的第二个代码示例的问题是,无论您的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(即:不需要运行整个循环),从而使代码更

答案 3 :(得分:0)

这是使用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'),
);

答案 4 :(得分:0)

这样做。代码中的问题是,如果第一项不符合条件,您将立即返回。

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";    
}

答案 5 :(得分:0)

函数/方法中的

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"))