我正在努力检查数组中的数组。似乎 const ReportRoute = (props) => {
const [input, setInput] = useState('');
const testObject1 = {
name: {input},
}
return (
<div>
<input value={input} onInput={e => setInput(e.target.value)} />
<Link
to={{
pathname: `api/report/name`,
search: queryString.stringify(testObject1),
}}
>
Download {props.type} report
</Link>
</div>
);
};
方法不是为此设计的,因为在这种情况下它总是返回include()
。以下是与false
相同的场景的示例。也许我需要的只是语法帮助,欢迎任何想法。
indexOf
当然,以上返回arr = [1,[9,9],3,4,5];
if (arr.indexOf(el) !== -1) {
console.log(`the array contains ${el}`);
} else {
console.log(`doesn't contain ${el}`);
}
代表1、3、4、5,true
代表2。现在是问题所在。我正在尝试使用类似false
的数组来填充此方法,以查看是否已经存在。
[9,9]
另一方面,以下内容还可以,这使我认为这只是语法问题(?)
let el = [9,9];
// console: "doesn't contain 9,9"
我通过编写带有let el = arr[1];
// console: "the array contains 9,9"
循环的检查器函数找到了解决该问题的方法,但是随着您添加需求,这很快变得很庞大。我想知道一种更聪明的方法。
谢谢。
答案 0 :(得分:3)
您遇到的问题是数组是引用类型。因此,仅当两个数组引用相同的基础数组时,比较两个数组才返回true;对于不同的数组,即使它们具有相同的值,也将返回false。
const arr1 = [1, 2];
const arr2 = [1, 2];
const arr3 = arr1;
console.log(arr1 === arr3);
console.log(arr1 !== arr2);
要解决您的问题,您的include
函数需要按值比较(深度比较),只需使用JSON.stringify()
即可做到这一点。
此方法快速但有局限性,当您具有简单的JSON样式对象而内部没有方法和DOM节点时,此方法就可以使用
有关JavaScript中的对象比较,请参见此SO post。
这是一个有效的示例:
function include(arr, value) {
const stringifiedValue = JSON.stringify(value);
for (const val of arr) {
if (JSON.stringify(val) === stringifiedValue) {
return true;
}
}
return false;
}
console.log(include([1, 2, 3, 4], 3));
console.log(include([1, 2, 3, [1, 2]], [1, 2]));
console.log(include([1, 2, 3, [1, 2]], [1, 2, 3]));
这是另一种方式,无需JSON.stringify()
即可进行此深度比较,它适用于内部数组和标量值:
function include(arr, value) {
const valArity = Array.isArray(value) ? value.length : 1;
for (let item of arr) {
if (valArity > 1 && Array.isArray(item) && item.length === valArity) {
if (item.every((val, i) => val === value[i])) {
return true;
}
} else if (item === value) {
return true;
}
}
return false;
}
console.log(include([1, 2, 3, 4], 3));
console.log(include([1, 2, 3, [1, 2]], [1, 2]));
console.log(include([1, 2, 3, [1, 2]], [1, 2, 3]));
console.log(include([1, 2, 'abc', 4], 'abc'));
这是经过修改的版本,适用于具有标量属性,数组和标量的简单对象:
function include(arr, value) {
const valArity = Array.isArray(value) ? value.length : 1;
const isObject = value instanceof Object;
for (let item of arr) {
if (valArity > 1 && Array.isArray(item) && item.length === valArity) {
if (item.every((val, i) => val === value[i])) {
return true;
}
} else if (isObject && item instanceof Object && item) {
const numEntries = Object.keys(value).length;
const entries = Object.entries(item);
if (numEntries === entries.length) {
if (entries.every(([k, v]) => value[k] === v)) {
return true;
}
}
} else if (item === value) {
return true;
}
}
return false;
}
console.log(include([1, 2, 3, 4], 3));
console.log(include([1, 2, 3, [1, 2]], [1, 2]));
console.log(include([1, 2, 3, [1, 2]], [1, 2, 3]));
console.log(include([1, 2, { a: 1 }, 4], { a: 1 }));
console.log(include([1, 2, { a: 1, b: 2 }, 4], { a: 1 }));
console.log(include([1, 2, 'abc', 4], 'abc'));
答案 1 :(得分:1)
在这里,我们可以使用Array.prototype.some()
注意,我们添加了一个辅助方法来检查每个元素,我没有费心编写对象检查,但是您明白了。
经过调整以支持子数组
let arr = [1, [9, 9], 3, 4, 5];
let el = [9, 9];
let arr2 = [1, [1,[9, 9]], 3, 4, 5];
let el2 = [1,[9, 9]];
const someCheck = (item, compare) => {
if(typeof item !== typeof compare) return false;
if(typeof item === 'string') return item === compare;
if(typeof item === 'number') return item === compare;
if(Array.isArray(item)) {
console.log('checking array');
return item.reduce((accum, o, i) => accum && (someCheck(o,compare[i])));
}
// no plain object support yet.
return false;
}
if (arr.some(e => someCheck(e, el))) {
console.log(`the array contains ${el}`);
} else {
console.log(`doesn't contain ${el}`);
}
if (arr2.some(e => someCheck(e, el2))) {
console.log(`the array contains ${el2}`);
} else {
console.log(`doesn't contain ${el2}`);
}
答案 2 :(得分:-1)
您需要遍历数组并检查每个元素是否为数组,然后检查每个索引。像这样:
let arr = [1,[9,9],3,4,5];
let el = [9,9];
let contains = true;
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
var equals = true
if(arr[i].length !== el.length)
equals = false;
for(var j = arr[i].length; j--;) {
if(arr[i][j] !== el[j])
equals = false;
}
if (equals) {
contains = true;
break;
}
} else {
if (arr.indexOf(el) !== -1){
contains = true;
break;
}
else{contains = false;}
}
}
if (contains) {
console.log(`the array contains ${el}`);
} else {
console.log(`doesn't contain ${el}`)
}