谁能告诉我为什么我的JS不遍历循环并删除数组中非“ 10”的项?
据我了解,它应该检查数组中的每个项目并删除非10的项目,然后返回其余的“ 10”项目。
我当前的输出是:[ <1 empty item>, 10, 50, 10 ]
我看到了一些答案,它们创建了一个单独的数组并将10的项目压入其中,然后返回该数组,但是为什么我的代码不起作用?
function getElementsThatEqual10AtProperty(obj, key) {
if (obj.key.length === 0) {
return [];
} else if (!obj.hasOwnProperty(key)) {
return [];
} else {
for (var i = 0; i < obj.key.length; i++) {
if (obj[key][i] !== 10) {
delete obj[key][i];
}
return obj.key;
}
}
}
var obj = {
key: [1000, 10, 50, 10]
};
var output = getElementsThatEqual10AtProperty(obj, 'key');
console.log(output);
答案 0 :(得分:1)
主要问题是您正在循环内执行return
,这意味着该函数在您的第一次迭代中碰到该行时将完全退出。
第二个问题更多是一个建议,但我不建议使用delete
。删除对象属性后, delete
不会更新数组的length
或索引。
var array = [1, 2, 3, 4];
delete array[0];
console.log(array.length);
假设,您可以将.filter(n=>n)
链接到它,一切都会好起来,但它仍然是多余的一组不必要的迭代。
从数组中过滤项目的最简单方法是使用以下名称的方法:Array.filter()
您更新后的功能可能看起来像这样。
function getElementsThatEqual10AtProperty(obj, key) {
if (Array.isArray(obj[key]) //Is it an array?
return obj[key].filter(n => n === 10); //Filter it for 10s
else
return [];
}
var obj = {
key: [1000, 10, 50, 10]
};
var output = getElementsThatEqual10AtProperty(obj, 'key');
console.log(output);
或者,如果您希望简洁:
const get10s = (obj, key) => Array.isArray(obj[key]) ? obj[key].filter(n => n === 10) : [];
var obj = { key: [1000, 10, 50, 10] };
console.log( get10s(obj, 'key') );
答案 1 :(得分:1)
为什么您的代码无法正常工作
return
语句位于for循环内,因此一旦您的if
条件失败,它将立即返回控制。delete
,它将删除该元素,但其他元素的索引仍与以前相同。这样您会得到类似[undefined,10,undefined,10]的信息。这是您的代码的工作模式。
function getElementsThatEqual10AtProperty(obj, key) {
if (obj.key.length === 0) {
return [];
} else if (!obj.hasOwnProperty(key)) {
return [];
} else {
let temp = []
for (var i = 0; i < obj.key.length; i++) {
if (obj[key][i] == 10) {
temp.push(obj[key][i])
}
}
return temp;
}
}
var obj = {
key: [1000, 10, 50, 10]
};
var output = getElementsThatEqual10AtProperty(obj, 'key');
console.log(output);
但是我建议您使用它,因为它既干净又简单
function getElementsThatEqual10(array) {
return array.filter(element => element === 10);
}
var obj = {
key: [1000, 10, 50, 10]
};
var output = getElementsThatEqual10(obj.key);
console.log(output);
答案 2 :(得分:1)
如果您愿意使用其他方法,则可以尝试使用filter
来解析所要获取的值:
const getElementsThatEqual10AtProperty = (obj, key) => obj[key].filter(v => v === 10)
var obj = {
key: [1000, 10, 50, 10]
};
var output = getElementsThatEqual10AtProperty(obj, 'key');
console.log(output);
鉴于您当前的方法,存在三个问题:
obj.key
的地方使用obj[key]
delete obj[key][i]
不会表现出预期的效果。正如@TinyGiant所提到的,“它不会对索引重新排序以删除结果的空槽。” return obj.key
应该为return obj[key]
,并且应该将其移到循环外,因为它在第一次迭代结束时就退出了循环如果要保留此方法,我建议使用obj[key].splice(i,1)
而不是delete
,这会改变数组。但是,由于要对活动数组进行突变,由于元素已移动,因此还必须修改i
。见下文:
function getElementsThatEqual10AtProperty(obj, key) {
if (obj[key].length === 0) {
return [];
} else if (!obj.hasOwnProperty(key)) {
return [];
} else {
for (var i = 0; i < obj.key.length; i++) {
if (obj[key][i] !== 10)
obj[key].splice(i--,1) // remove value then alter i
}
return obj[key] // moved outside of the loop
}
}
var obj = {
key: [1000, 10, 50, 10]
};
var output = getElementsThatEqual10AtProperty(obj, 'key');
console.log(output);
答案 3 :(得分:0)
这是一种奇怪的方法设计。它使变异并返回结果?通常,最好选择其中一个(请参见CQS)。
此外,您的原始方法过度耦合到对象结构。最好使它仅在数组上运行,而不留任何对象键。
请考虑以下内容:
function getElementsThatEqual10(array) {
return array.filter(n => n == 10);
}
var obj = {
key: [1000, 10, 50, 10]
};
var output = getElementsThatEqual10(obj.key);
console.log(output);
答案 4 :(得分:-1)
早期返回返回仅完成删除第一个元素后退出循环(由于对象不相关,此处简化为简单数组):
let objKey = [1000, 10, 50, 10];
for (var i = 0; i < objKey.length; i++) {
if (objKey[i] !== 10) {
// Here it deletes 1000, the first element
delete objKey[i];
}
// then it returns [undefined, 10, 50, 10]
return objKey;
}
您可以将return
语句从循环中移到getElementsThatEqual10AtProperty
函数结束之前。
其他人已经提出了更优雅的方法。
答案 5 :(得分:-2)
您可以这样写以删除正确的项目,因为您正在for循环中返回,因此仅删除了第一项。
您可以使用splice方法而不是delete,因为delete仅删除引用,而不删除数组的位置。
function getElementsThatEqual10AtProperty(obj, key) {
if (obj[key].length === 0) {
return [];
} else if (!obj.hasOwnProperty(key)) {
return [];
} else {
for (var i = 0; i < obj[key].length; i++) {
if (obj[key][i] !== 10) {
obj[key].splice(i, 1);
i--;
}
}
return obj[key];
}
}
var obj = {
key: [1000, 10, 50, 10]
};
var output = getElementsThatEqual10AtProperty(obj, 'key');
console.log(output);