Мне нужно сравнить два массива и получить на выходе один массив, объекты сравниваются внутри

У меня есть следующий код, который является ответом на предыдущий вопрос, который у меня был, но вместо того, чтобы испортить этот вопрос Я хочу повторить, что я на самом деле ищу, потому что я могу кажется, не понял.

Предполагаемый результат, который я хочу, - это всего лишь один объект с измененными значениями и таким идентификатором. Однако это необходимо изменить, чтобы он не складывался, как сейчас, при каждом изменении экземпляра есть другой консольный объект. И я просто хочу, чтобы новейшее сравнение утешало, игнорируя предыдущее. Надеюсь, это имеет смысл. Могу объяснить дальше, если нужно.

Когда я говорю о накоплении, я имею в виду, что при следующем изменении состояния он обслуживает два элемента, затем три, и так далее, и четвертый. Мне просто нужно последнее изменение, чтобы я мог запустить мутацию и обновить свою БД.

Желаемый результат №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 зависит от состояния использования, поэтому оно всегда меняется.

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, были только недавно измененные свойства, что означает, что пользователь оставил ввод, и я запускаю свою сохраненную мутацию.

Вот скриншот, показывающий несколько свойств в объекте, у него должно быть только одно, кроме идентификатора. Он должен заменять объект целиком, а не добавлять к нему каждое сравнение. В массиве также есть два объекта, мне нужен только последний измененный, потому что я запускаю мутации сохранения при каждом сравнении, и мне нужен только один объект с двумя полями: измененное поле и идентификатор.

объект


person Anders Kitson    schedule 13.03.2021    source источник
comment
Однако функция compareArray, которую вы используете, не является моим окончательным редактированием, способ, которым вы ее реализовали, приводит к повторной инициализации ключа col10 в новом состоянии для каждого ключа в объекте oldItem. Используйте функцию, которую я закончил из другого вопроса.   -  person a.mola    schedule 13.03.2021
comment
Я отредактировал свой ответ в последнем вопросе, когда вы попросили ключ col10. Вы снова запустили фрагмент?   -  person a.mola    schedule 13.03.2021
comment
этот фрагмент дает мне два объекта, и при каждом новом изменении данных в реакции добавляются еще два объекта. Так что это не совсем решает мою проблему. Мне просто нужен текущий объект состояния изменения, а не предыдущие, если это имеет смысл   -  person Anders Kitson    schedule 14.03.2021
comment
Я не понимаю, что вы имеете в виду, функция возвращает то, что отличается между двумя парами объектов, и возвращает это. И в каждом объекте есть два элемента. Это означает, что он всегда возвращает длину массивов oldState или saveData.   -  person a.mola    schedule 14.03.2021
comment
это трудно объяснить, ваш ответ несколько правильный. Я просто делаю плохую работу, объясняя, что мне нужно. Я обновлю свой вопрос здесь с более подробной информацией в ближайшее время. спасибо за помощь до сих пор   -  person Anders Kitson    schedule 14.03.2021
comment
@a.mola Я добавил обновление, надеюсь, теперь оно имеет больше смысла. Я все еще выясняю это. Спасибо   -  person Anders Kitson    schedule 14.03.2021
comment
Давайте продолжим это обсуждение в чате.   -  person a.mola    schedule 14.03.2021


Ответы (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)

person Soufiane Boutahlil    schedule 13.03.2021
comment
Это не совсем так. Я недостаточно хорошо объясняю проблему. Я собираюсь вернуться к чертежной доске и пройти через это медленнее, чтобы решить. Спасибо - person Anders Kitson; 14.03.2021

Эта функция будет перебирать оба состояния и сравнивать каждое значение. Если новое значение не совпадает, оно добавит его к объекту. Если у объекта есть свойства, то он добавит свойство 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));

person Emiel Zuurbier    schedule 14.03.2021