根据对象的 id 比较两个对象数组



我试图根据它们的id比较两个对象数组并返回一个boolean。我已经根据is_selected === 1从两个数组中过滤出了项目。如果两个数组的IDs相同,则返回isModifiedfalse或返回true。

都是一个复选框数组。初始数组是我从后端得到的,当前数组由用户修改。可以通过更改复选框来更改当前数组的长度。

使用我当前的方法,for循环从第二次开始就不会执行。

function cancel() {
const initialArr = [
{id: 8, name: "Celery", is_selected: 1},
{id: 9, name: "Crustaceans", is_selected: 1},
{id: 2, name: "Eggs", is_selected: 1},
{id: 6, name: "Fish", is_selected: 1},
];
const currentArr = [
{id: 8, name: "Celery", is_selected: 1},
{id: 4, name: "Mustard", is_selected: 1},
{id: 2, name: "Eggs", is_selected: 1},
{id: 6, name: "Fish", is_selected: 1},
];
let isModified!: boolean;
for (let index = 0; index < currentArr.length; index++) {
const id = currentArr[index].id;
isModified = initialArr.some((o2) => o2.id !== id);
if (isModified) break;
}
if(isModified){
alert('are you sure?');
} else {
console.log('exit the page');
}
}

代码中的for循环没有问题。你可以做一些改变来改进它

  • 使用map而不是数组来更快地查找。每次在数组上运行迭代是缓慢的,并且它只会随着arr的大小增加而增加。
  • 如果值在currentArr中更改,则签入每次迭代。

您还需要确定当当前目录中有新项时将发生什么。E换了新id),是算修改还是不算修改?

假设上面问题的答案是肯定的,下面的代码应该可以工作

function cancel() {
const initialArr = [
{id: 8, name: "Celery", is_selected: 1},
{id: 9, name: "Crustaceans", is_selected: 1},
{id: 2, name: "Eggs", is_selected: 1},
{id: 6, name: "Fish", is_selected: 1},
];
const initalArrMap = initialArr.reduce((prev, current) => {
return {...prev, [current.id]: current}
}, {});
const currentArr = [
{id: 8, name: "Celery", is_selected: 1},
{id: 9, name: "Mustard", is_selected: 1},
{id: 2, name: "Eggs", is_selected: 1},
{id: 6, name: "Fish", is_selected: 1},
{id: 9, name: "Fish", is_selected: 1},
];
let isModified = currentArr.length !== initialArr.length;
if(!isModified){
for (let index = 0; index < currentArr.length; index++) {
const id = currentArr[index].id;
isModified = initalArrMap[id] ? initalArrMap[id].is_selected != currentArr[index].is_selected : true;
if (isModified) break;
}
}
if(isModified){
alert('are you sure?');
} else {
console.log('exit the page');
}
}
cancel();

注意:我只检查is_selected是否改变,以确定当前r是否改变。

编辑:在currentArrinitialArr长度不相等的情况下增加了检查

问题是使用initialArr.some((o2) => o2.id !== id)

some()方法测试是否至少有一个数组中的元素通过所提供的函数实现的测试。如果在数组中找到所提供函数为其返回true的元素,则返回true;否则返回false。

您想检查什么?如果initialArr没有currentArrid,这意味着我的currentArr被修改了,所以你需要尝试这个:

!initialArr.some((o2) => o2.id === id)

const initialArr = [
{ id: 8, name: "Celery", is_selected: 1 },
{ id: 9, name: "Crustaceans", is_selected: 1 },
{ id: 2, name: "Eggs", is_selected: 1 },
{ id: 6, name: "Fish", is_selected: 1 }
];
const currentArr = [
{ id: 8, name: "Celery", is_selected: 1 },
{ id: 4, name: "Mustard", is_selected: 1 },
{ id: 2, name: "Eggs", is_selected: 1 },
{ id: 6, name: "Fish", is_selected: 1 }
];
let isModified = false;
for (let index = 0; index < currentArr.length; index++) {
const id = currentArr[index].id;
isModified = !initialArr.some((o2) => o2.id === id);
if (isModified)
break;
}
if (isModified) {
alert('are you sure?');
} else {
console.log('exit the page');
}

  1. 将第一个数组的每个元素与第二个数组的所有元素进行比较
  2. 排序键将确保它给出正确的结果,如果键的顺序改变。
  3. 一旦找到第一个不同的对象,它就会打破循环。

function cancel() {
const a = [
{id: 8, name: "Celery", is_selected: 1},
{id: 9, name: "Crustaceans", is_selected: 1},
{id: 2, name: "Eggs", is_selected: 1},
{id: 6, name: "Fish", is_selected: 1},
];
const b = [
{id: 8, name: "Celery", is_selected: 1},
{id: 4, name: "Mustard", is_selected: 1},
{id: 2, name: "Eggs", is_selected: 1},
{id: 6, name: "Fish", is_selected: 1},
];
let isModified;
let ctr =0;
for (let index = 0; index < a.length; index++) {
for(let j=0; j<b.length; j++){
var aKeys = Object.keys(a[index]).sort();
var bKeys = Object.keys(b[j]).sort();
if(aKeys.toString()!== bKeys.toString()){
ctr++;
break;
}
}
}
if(ctr){
alert('Modified');
} else {
console.log('not modified');
}
}
cancel();

数组中每个元素都返回true的原因不是逻辑错误而是语法错误,检查一下对象数组它们没有逗号分隔数组元素

最新更新