在我的情况下,检查数组中的数组是否相同的最佳方法是什么?
var arrSession = [
{
type: '1',
usecase: [ '1' ]
},
{
type: '1',
usecase: [ '1' ]
}
];
var checkUsecase = arrSession.every(isSame);
function isSame(obj, index, arr) {
if (index === 0) {
return true;
} else {
return (
(obj.type === arr[index - 1].type) &&
(obj.usecase === arr[index - 1].usecase)
);
}
}
console.log('checkUsecase:');
console.log(checkUsecase);
数组中的“usecase”对象是一个字符串“”,并且 isSame 函数可以工作。但现在它们也是数组。如何更改 isSame 函数?
这是一个小提琴:https://jsfiddle.net/3j0odpec/
首先我们创建一些递归比较函数来遍历嵌套数组/对象。然后我们对数组运行它,比较当前项与前一项是否相等。
而且它绝对比比较 OP 数据的 JSON.stringified 数组项更快:
const arrSession = [
{
type: '1',
usecase: ['1']
},
{
type: '1',
usecase: ['1']
}
];
const isSameItems = arrSession.every((item, idx, arr) => idx === 0 || isSame(item, arr[idx - 1]));
console.log('the array has all items the same: ', isSameItems);
function isSame(a, b) {
const iterator = Array.isArray(a) && Array.isArray(b) ? a.keys() :
(typeof a === 'object') && (typeof b === 'object') ? Object.keys(a) : null;
if (iterator) {
for (const i of iterator) {
if (!isSame(a[i], b[i])) {
return false;
}
}
return true;
}
return a === b;
}
<script benchmark data-count="1">
const arrSession = JSON.parse(JSON.stringify(Array.from({ length: 300000 }).reduce(arr => arr.push(...[
{
type: '1',
usecase: ['1'],
child: {
type: '1',
usecase: ['1'],
child: {
type: '1',
usecase: ['1'],
child: {
type: '1',
usecase: ['1'],
}
}
},
child: {
type: '1',
usecase: ['1'],
}
}
]) && arr, [])));
// @benchmark JSON.stringify
arrSession.every((item, idx, arr) => idx === 0 || JSON.stringify(item) === JSON.stringify(arr[idx - 1]));
// @benchmark recursive isSame
function isSame(a, b) {
const iterator = Array.isArray(a) && Array.isArray(b) ? a.keys() :
(typeof a === 'object') && (typeof b === 'object') ? Object.keys(a) : null;
if (iterator) {
for (const i of iterator) {
if (!isSame(a[i], b[i])) {
return false;
}
}
return true;
}
return a === b;
}
// @run
arrSession.every((item, idx, arr) => idx === 0 || isSame(item, arr[idx - 1]));
</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>
some
的比较方法...
const isFullItemEquality = arrSession
.every((item, idx, arr) =>
idx === 0 || isDeepDataStructureEquality(item, arr[idx - 1])
);
...只是它不利用
JSON.stringify
。
对于 JSON 一致数据结构的相同性/相等性比较,其中性能也很重要,可以考虑采用以下
isDeepDataStructureEquality
... 的递归实现
<script>
// implemented by Peter Seliger
function isDeepDataStructureEquality(a, b) {
let isEqual = Object.is(a, b);
if (!isEqual) {
if (Array.isArray(a) && Array.isArray(b)) {
isEqual = (a.length === b.length) && a.every(
(item, idx) => isDeepDataStructureEquality(item, b[idx])
);
} else if (
a && b
&& (typeof a === 'object')
&& (typeof b === 'object')
) {
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
isEqual = (aKeys.length === bKeys.length) && aKeys.every(
(key, idx) => isDeepDataStructureEquality(a[key], b[key])
);
}
}
return isEqual;
}
</script>
<script>
// implemented by Alexander Nenashev
function isSame(a, b) {
const iterator = Array.isArray(a) && Array.isArray(b) ? a.keys() :
(typeof a === 'object') && (typeof b === 'object') ? Object.keys(a) : null;
if (iterator) {
for (const i of iterator) {
if (!isSame(a[i], b[i])) {
return false;
}
}
return true;
}
return a === b;
}
</script>
<script benchmark data-count="10">
const arrSession = JSON.parse(JSON.stringify(Array
.from({ length: 300000 })
.reduce(arr => arr.push(...[{
type: '1',
usecase: ['1'],
child: {
type: '1',
usecase: ['1'],
child: {
type: '1',
usecase: ['1'],
child: {
type: '1',
usecase: ['1'],
},
},
},
child: {
type: '1',
usecase: ['1'],
}
}]) && arr, [])));
// countercheck implementations with an unequal data structure.
// arrSession.at(-1).child.usecase[0] = 0;
// @benchmark JSON.stringify
arrSession.every((item, idx, arr) =>
idx === 0 || JSON.stringify(item) === JSON.stringify(arr[idx - 1])
);
// @benchmark recursive isSame
arrSession.every((item, idx, arr) =>
idx === 0 || isSame(item, arr[idx - 1])
);
// @benchmark recursive isDeepDataStructureEquality
arrSession.every((item, idx, arr) =>
idx === 0 || isDeepDataStructureEquality(item, arr[idx - 1])
);
</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>