Как объединить два объекта с разными свойствами

#javascript #ecmascript-6

#javascript #ecmascript-6

Вопрос:

У меня есть что-то вроде этого :

 let user = [
{
    name: "step-one",
    values: {companyName: "Name", address: "company address"}
},
{
    name: "step-two",
    values: {name: "User", mobile: 0123}
},
{
    name: "step-three",
    values: [
              {file: "companyLogo", values: {active: true, fileName: "some name"}},
              {file: "avatar", values: {active: true, fileName: "file name"}}
            ]
}
]
  

Я хочу получить только значения и поместить их в новый объект. Таким образом, что-то вроде :

 let wantedResult = {
    companyName: "Name",
    address: "company address",
    name: "User",
    mobile: 0123,
    files: [
            {file: "companyLogo", values: {active: false, fileName: "some name"}},
            {file: "avatar", values: {active: false, fileName: "file name"}}
        ]
};
  

Любой совет, как я могу это сделать?

Комментарии:

1. Перебирайте их и присваивайте их вашему wantedresult? Пожалуйста, покажите нам, что вы пробовали.

2. третий шаг непоследователен. Должно ли это быть values: {files: [ {...}, {...} ] } ?

Ответ №1:

Вы можете попробовать это!

 let user = [{
  name: "step-one",
  values: {
    companyName: "Name",
    address: "company address"
  }
}, {
  name: "step-two",
  values: {
    name: "User",
    mobile: 0123
  }
}, {
  name: "step-three",
  values: [{
    file: "companyLogo",
    values: {
      active: true,
      fileName: "some name"
    }
  }, {
    file: "avatar",
    values: {
      active: true,
      fileName: "file name"
    }
  }]
}]

var wantedResult = Object.assign({}, user[0].values, user[1].values, {files: user[2].values})
console.log(wantedResult)  

Ответ №2:

Это немного сложно из-за массива файлов, но я бы сделал это так:

 var wantedResult = user.reduce((result, step) => {
    var values = Array.isArray(step.values) ? { files: step.values } : step.values;
    return Object.assign({}, result, values)
}, {});
  

Конечно, это будет работать только для той структуры, которую вы предоставили. Если у вас есть больше объектов, которые имеют массив в свойстве ‘values’, вам нужно пересмотреть подход.

Комментарии:

1. И, как упоминал iblamefish в комментарии выше, было бы гораздо разумнее, если бы вы изменили структуру «третьего шага», чтобы она была согласованной и имела объект в свойстве «значения» вместо массива. В этом случае вы можете удалить назначение значений var из моего кода и просто использовать назначение объекта с помощью step.values .

Ответ №3:

Шаг 3 несовместим с другими. Если возможно, сделайте его согласованным, чтобы иметь: values: files: [ { file1_data }, { file2_data } ] .

После устранения несоответствия вы можете повторить каждый из шагов и добавить новые свойства к результату.

 let wantedResult = user.reduce(function(result, spec) {
  Object.keys(spec.values).forEach(function(key) {
     result[key] = spec.values[key];
  });
  return resu<
}, {});
  

Если невозможно изменить шаг 3, вы можете сделать его немного менее чистым:

 let wantedResult = user.reduce(function(result, spec) {
  if (spec.name === "step-three") {
    result.files = spec.values;
  }
  else {
    Object.keys(spec.values).forEach(function(key) {
       result[key] = spec.values[key];
    });
  }
  return resu<
}, {});