Лучший способ создать НОВЫЙ и РАЗЛИЧНЫЙ Объект из другого объекта - PullRequest
0 голосов
/ 25 февраля 2019

Я хочу иметь возможность взять объект

const objectOriginal = {
  nestedObject: {
   someValue: 1
  }
}

Создать новый объект из приведенного выше и изменить его значение на

const newObject = {
  nestedObject: {
   someValue: 33
  }
}

У меня есть большой вложенный объектобъекты как мой оригинал, и я хочу создать новый на основе этого оригинала.Проблема в том, что мне нужно, чтобы эти два объекта были разными, а не из одной цепочки прототипов.

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

const originalObject = {
  nested1: {
    id: "nested1"
    value: 1
  },
  nested2: {
    id: "nested2"
    value: 2
  },
  nested3: {
    id: "nested3"
    value: 3
  }
}

const valueToChange = "nested1"

const createNewObject = (originalObject, valueToChange) => { 
  const originalObjectToArray = Object.values(originalObject)

  const temporaryArray = originalObjectToArray.filter(object => object.id !== valueToChange)

  const newNestedObject = {
    id: valueToChange,
    value: 33
  }
  temporaryArray.push(newNestedObject)

  const newAndDifferentObject = {}
  for (let obj of temporaryArray) {
    newAndDifferentObject[obj.id] = obj
  }
  return newAndDifferentObject
}

Это решение работает, но я чувствую, что должен быть лучший способ достичь этого?Если я хочу создать новый и другой объект, мне не следует (по крайней мере, я бы надеялся, что нет) изменить его на массив, чтобы просто вернуть его обратно на объект.Любой совет будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Я буду использовать Object.assign () для этого.Мы создаем новый пустой объект, назначаем все исходные свойства исходного объекта, а затем назначаем новый вложенный объект.Метод позаботится о замене существующих свойств новыми (Подробнее здесь: Объединение объектов с одинаковыми свойствами ).

const originalObject = {
  nested1: {id: "nested1", value: 1},
  nested2: {id: "nested2", value: 2},
  nested3: {id: "nested3", value: 3}
};

const createNewObject = (originalObj, valToChange, newVal) =>
{
    const newObj = {id: valToChange, value: newVal};
    return Object.assign({}, originalObj, {[valToChange]: newObj});
};

// Example of replacements.
console.log(createNewObject(originalObject, "nested1", 33));
console.log(createNewObject(originalObject, "nested2", 99));

// Example of a new property (none of the original are replaced)
console.log(createNewObject(originalObject, "nested4", 44));

Вы можете даже обобщить предыдущий метод, чтобы принять массив пар типа [valToChange, newVal], чтобы создать новый object с несколькими изменениями:

const originalObject = {
  nested1: {id: "nested1", value: 1},
  nested2: {id: "nested2", value: 2},
  nested3: {id: "nested3", value: 3}
};

const createNewObject = (originalObj, updateList) =>
{
    let newObjs = updateList.reduce((acc, [k, v]) =>
    {
        acc[k] = {id: k, value: v};
        return acc;
    }, {});

    return Object.assign({}, originalObj, newObjs);
};

console.log(createNewObject(
    originalObject,
    [["nested1", 33], ["nested2", 99], ["nested4", 44]]
));
0 голосов
/ 25 февраля 2019

Ваша проблема в том, что обе переменные указывают на один и тот же объект (поверхностная копия).То, что вы делаете, это глубокая копия, и есть более простой способ сделать это, используя JSON:

function jsonCopy(src) {
    return JSON.parse(JSON.stringify(src));
}

Передав исходный объект как src, он преобразует его в строку JSON и анализирует егообратно к объекту, выполняя глубокую копию вашего объекта и возвращая его.

...