首页 > 解决方案 > 我需要比较两个数组并让输出是一个数组,在里面比较对象

问题描述

我有以下代码,这是我之前的问题的答案,但我不想弄乱那个问题,而是想重申我真正在寻找什么,因为我似乎无法掌握它。

我想要的预期输出现在只是一个具有更改值和 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。

对象

标签: javascriptreactjslodashautosavearray.prototype.map

解决方案


此函数将遍历两种状态并比较每个值。如果新值不同,它会将其添加到对象中。如果对象具有属性,那么它将添加该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));


推荐阅读