【问题标题】:I need to compare two arrays and have the output be one array, objects being compared inside我需要比较两个数组并让输出是一个数组,在里面比较对象
【发布时间】:2021-06-11 12:43:37
【问题描述】:

我有以下代码,这是我上一个问题的答案,但我不想弄乱question,而是想重申我真正在寻找的东西,因为我似乎无法掌握它。

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

【问题讨论】:

  • 您使用的 compareArray 函数不是我的最终编辑,但您实现它的方式使 col10 键重新初始化为 @987654331 中每个键的新状态@ 目的。使用我从另一个问题中完成的功能。
  • 当您询问col10 键时,我在最后一个问题中编辑了我的答案。你又运行了 sn-p 吗?
  • sn-p 给了我两个对象,并且在 react 中的每个新数据更改时,都会添加另外两个对象。所以它并不能完全解决我的问题。如果有意义的话,我只需要当前的更改状态对象而不是以前的更改状态对象
  • 我不明白你的意思,该函数返回两对对象之间的不同之处并返回。每个对象中有两个元素。这意味着它总是返回 oldStatesaveData 数组的长度
  • 这很难解释,你的回答有些正确。我只是在解释我需要什么方面做得不好。我会尽快在这里更新我的问题,并提供更好的细节。感谢您迄今为止的帮助

标签: javascript reactjs lodash autosave array.prototype.map


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我认为您需要将对象合并为只有一个,如下所示:

    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;
    }
    
    let myObject = {}
    oldState.map((old, i) => [old, saveData[i]]).forEach((item) => myObject = {...myObject, ...compareArray(...item)}
    );
    console.log(myObject)

    【讨论】:

    • 不完全是。我没有很好地解释这个问题。我要回到绘图板上,慢慢地解决这个问题。谢谢
    猜你喜欢
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多