我有一个对象数组:
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"));
答案 0 :(得分:3)
这里的问题是您正在尝试做两件事。
为此,嵌套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"))