javascript - 我需要比较两个数组并让输出是一个数组,在里面比较对象
问题描述
我有以下代码,这是我之前的问题的答案,但我不想弄乱那个问题,而是想重申我真正在寻找什么,因为我似乎无法掌握它。
我想要的预期输出现在只是一个具有更改值和 id 的对象。但是,这需要更改,因此它不会像现在代码那样在每次实例更改时叠加,还有另一个对象受到控制。我只想让最新的比较得到安慰,而忽略前一个。希望这是有道理的。如果需要,我可以进一步解释。
当我说堆叠时,我的意思是,下次状态改变时它会控制两个项目,然后是三个,依此类推,第四个。我只想要最新的更改,以便我可以运行突变并更新我的数据库
状态改变后的期望结果#1
{col0:"snappy", col10:"292959180223939085"}
状态改变后的期望结果#2
{col0:"some state change", col10:"292959180223939085"}
const oldState = [{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "okok",
"col3": true,
"col4": 7,
"col5": 5,
"col6": "Curation",
"col7": "fsaf",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615646495/catalog/sse5zxtklsj3ib730zjy.png",
"col9": 4,
"col10": "292959180223939085"
},
{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "fdsafd",
"col3": true,
"col4": 3,
"col5": 3,
"col6": "Curation",
"col7": "fdsfsa",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615657360/catalog/qpudbgkrvftjlo5c1yma.png",
"col9": 5,
"col10": "292970573359743501"
}
]
const saveData = [{
"col0": "Snappy",
"col1": "2021-03-31",
"col2": "okok",
"col3": true,
"col4": 7,
"col5": 5,
"col6": "Curation",
"col7": "fsaf",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615646495/catalog/sse5zxtklsj3ib730zjy.png",
"col9": 4,
"col10": "292959180223939085"
},
{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "fdsafd",
"col3": true,
"col4": 3,
"col5": 3,
"col6": "Curation",
"col7": "fdsfsa",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615657360/catalog/qpudbgkrvftjlo5c1yma.png",
"col9": 5,
"col10": "292970573359743501"
}
]
function compareArray(oldItem, newItem) {
const compared = {};
for (const key in oldItem) {
if ((key == 'col10' || oldItem[key] != newItem[key]) && Object.hasOwnProperty.call(newItem, key) && Object.hasOwnProperty.call(oldItem, key)) {
compared[key] = newItem[key];
}
}
return compared;
}
oldState.map((old, i) => [old, saveData[i]]).forEach((item) => console.log(compareArray(...item)));
这是我实现它的方式,saveData 状态取决于到达 useState,所以它总是在变化。
function AutoSave({ saveData, cookieBearer, oldState }) {
const [saving, setSaving] = useState(false);
const [
updateDecorDoc,
{ data: docData, loading: savingMutate },
] = useMutation(UPDATE_DECOR_DOC, {
context: {
headers: {
authorization: cookieBearer,
},
},
});
const debounceSave = useCallback(
debounce(async (saveData) => {
setSaving(true);
function compareArray(oldItem, newItem) {
const compared = {};
for (let key in oldItem) {
if (oldItem[key] != newItem[key]) {
compared[key] = newItem[key];
compared["col10"] = newItem["col10"];
}
}
return compared;
}
oldState
.map((old, i) => [old, saveData[i]])
.forEach((item) => {
var test = compareArray(...item);
console.log(test)
});
})
);
useEffect(() => {
if (saveData) {
debounceSave(saveData);
}
}, [saveData, debounceSave]);
if (saving) return <p>saving</p>;
if (!saving) return <p>Auto Save on</p>;
}
更新:每次比较后,它都会向对象添加属性,我希望每次我的 onblur 事件触发时只有最近更改的属性,这意味着用户已经离开输入并且我触发了我的保存突变。
这是一个屏幕截图,显示了对象中的多个属性,它应该只有一个,然后是 ID。它应该一起替换对象而不是每次比较都添加到它。数组中还有两个对象,我只需要最近更改的一个,因为我在每次比较时都会触发保存突变,并且只需要一个具有两个字段的对象,即更改的字段和 id。
解决方案
此函数将遍历两种状态并比较每个值。如果新值不同,它会将其添加到对象中。如果对象具有属性,那么它将添加该col10
属性并将其添加到已更改对象的列表中。
const getStateDiff = (oldState, newState) => {
const differences = [];
for (let i = 0; i < oldState.length; i++) {
const oldStateKeys = oldState[i];
const newStateKeys = newState[i];
const entryDiff = {};
for (let key in oldStateKeys) {
if (
newStateKeys.hasOwnProperty(key) &&
oldStateKeys[key] !== newStateKeys[key]
) {
entryDiff[key] = newStateKeys[key];
}
}
if (Object.keys(entryDiff).length > 0) {
entryDiff['col10'] = newStateKeys['col10'];
differences.push(entryDiff);
}
}
return differences;
};
const oldState = [
{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "okok",
"col3": true,
"col4": 7,
"col5": 5,
"col6": "Curation",
"col7": "fsaf",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615646495/catalog/sse5zxtklsj3ib730zjy.png",
"col9": 4,
"col10": "292959180223939085"
},
{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "fdsafd",
"col3": true,
"col4": 3,
"col5": 3,
"col6": "Curation",
"col7": "fdsfsa",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615657360/catalog/qpudbgkrvftjlo5c1yma.png",
"col9": 5,
"col10": "292970573359743501"
}
];
const saveData = [
{
"col0": "Snappy",
"col1": "2021-03-31",
"col2": "okok",
"col3": true,
"col4": 7,
"col5": 5,
"col6": "Curation",
"col7": "fsaf",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615646495/catalog/sse5zxtklsj3ib730zjy.png",
"col9": 4,
"col10": "292959180223939085"
},
{
"col0": "Decor",
"col1": "2021-03-31",
"col2": "fdsaf",
"col3": true,
"col4": 3,
"col5": 3,
"col6": "Curation",
"col7": "fdsfsa",
"col8": "https://res.cloudinary.com/kitson-co/image/upload/v1615657360/catalog/qpudbgkrvftjlo5c1yma.png",
"col9": 5,
"col10": "292970573359743501"
}
];
console.log(getStateDiff(oldState, saveData));
推荐阅读
- sql - Laravel 多对多关系计数
- buildroot - ubuntu cp:无法统计
.tar.gz':没有这样的文件或目录 - python - 使用多个程序访问串口
- java - 将 Flyway 添加到已投入生产的项目中
- postgresql - 在 postgres 中匿名化 JSONB 的更好方法?
- c# - 总结在列表属性列表中
- reactjs - 在 useState 定义的对象中设置对象
- r - 为什么我在 R 中的摘要只包括我的一些变量?
- javascript - 使用 JavaScript 循环遍历复杂的 JSON
- python - 在 SQLAlchemy 中执行许多 dml 语句的最佳性能方式