Сопоставьте два массива для объединения разных данных в один, ЕСЛИ идентификатор элемента в javascript одинаков

#javascript #arrays

#javascript #массивы

Вопрос:

благодаря другому сообщению я смог продвинуться на шаг вперед в том, что, как я учил, было простым процессом. но, похоже, я не могу найти правильный способ объединить два массива в один, «группируя» по общему полю «id»…

Ниже приведен мой один массив:

 // editedItem.extra_tools ///

0:
{
    extra_tool_password: "tool data password"
    extra_tool_username: "tool data username"
    id_extra_tool: "8"
},
1:
{
    extra_tool_password: "tool data password"
    extra_tool_username: "tool data username"
    id_extra_tool: "1"
},
2:
{
    extra_tool_password: "tool data password"
    extra_tool_username: "tool data username"
    id_extra_tool: "7"
}

  

это должно быть объединено через id_extra_tool для:

 // this.extras //
0:
{
    extra_params: 1
    extra_tool_name: "tool 1"
    extra_tool_password: ""
    extra_tool_username: ""
    id_extra_tool: 1
}
1:
{
    extra_params: 1
    extra_tool_name: "tool 2"
    extra_tool_password: ""
    extra_tool_username: ""
    id_extra_tool: 7
}
{
2:
    extra_params: 0
    extra_tool_name: "tool 3"
    extra_tool_password: ""
    extra_tool_username: ""
    id_extra_tool: 8
  

чтобы получить

 //mergedArray //

if (this.editedItem.extra_tools.length) {
        var mergedArray = []
        this.editedItem.extra_tools.map(x => {
          this.extras.map(y => {
            if (x.id_extra_tool === y.id_extra_tool) {
              mergedArray.push(Object.assign(x, y))
            }
          })
        })

  

таким образом, конечный массив должен содержать «полные» данные из каждого массива, завершая каждый элемент, объединяющий данные с помощью id_extra_tool

 // merged //
0:
{
    extra_params: // TAKEN_BY: "Extras"
    extra_tool_name: // TAKEN_BY: "Extras"
    extra_tool_password:// TAKEN_BY: "extra_tools"
    extra_tool_username: // TAKEN_BY: "extra_tools"
    id_extra_tool: 1
}
1:
{
    extra_params: // TAKEN_BY: "Extras"
    extra_tool_name: // TAKEN_BY: "Extras"
    extra_tool_password:// TAKEN_BY: "extra_tools"
    extra_tool_username: // TAKEN_BY: "extra_tools"
    id_extra_tool: 7
}
{
2:
    extra_params: // TAKEN_BY: "Extras"
    extra_tool_name: // TAKEN_BY: "Extras"
    extra_tool_password:// TAKEN_BY: "extra_tools"
    extra_tool_username: // TAKEN_BY: "extra_tools"
    id_extra_tool: 8
  

Ответ №1:

Вы пытаетесь сравнить string с integer использованием === , которое неверно (используйте == вместо этого).

Лучше использовать .find для проверки, имеет ли каждый x элемент соответствующий объект в extras с тем же id_extra_tool :

 const editedItem = {
  extra_tools: [
    {
      extra_tool_password: "tool data password",
      extra_tool_username: "tool data username",
      id_extra_tool: "8"
    },
    {
      extra_tool_password: "tool data password",
      extra_tool_username: "tool data username",
      id_extra_tool: "1"
    },
    {
      extra_tool_password: "tool data password",
      extra_tool_username: "tool data username",
      id_extra_tool: "7"
    }
  ]
};
const extras = [
  {
    extra_params: 1,
    extra_tool_name: "tool 1",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 1
  },
  {
    extra_params: 1,
    extra_tool_name: "tool 2",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 7
  },
  {
    extra_params: 0,
    extra_tool_name: "tool 3",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 8
  }
];

if (editedItem.extra_tools.length) {

  var mergedArray = [];
  
  editedItem.extra_tools.map(x => {
  
    const y = extras.find(e => e.id_extra_tool == x.id_extra_tool);
    
    if (y) {
      mergedArray.push(Object.assign(x, y))
    }
  });
  
  console.log(mergedArray);
}  

Другим способом сделать это было бы использование .reduce :

 const editedItem = {
  extra_tools: [
    {
      extra_tool_password: "tool data password",
      extra_tool_username: "tool data username",
      id_extra_tool: "8"
    },
    {
      extra_tool_password: "tool data password",
      extra_tool_username: "tool data username",
      id_extra_tool: "1"
    },
    {
      extra_tool_password: "tool data password",
      extra_tool_username: "tool data username",
      id_extra_tool: "7"
    }
  ]
};
const extras = [
  {
    extra_params: 1,
    extra_tool_name: "tool 1",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 1
  },
  {
    extra_params: 1,
    extra_tool_name: "tool 2",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 7
  },
  {
    extra_params: 0,
    extra_tool_name: "tool 3",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 8
  }
];

if (editedItem.extra_tools.length) {

  const mergedArray = editedItem.extra_tools.reduce((acc,x) => {
  
    const y = extras.find(e => e.id_extra_tool == x.id_extra_tool);
    
    if (y) {
      acc.push(Object.assign(x, y))
    }
    
    return acc;
  }, []);
  
  console.log(mergedArray);
}  

Ответ №2:

id_extra_tool In editedItem.extra_tools и this.extras не имеют одного и того же типа (строка против числа), поэтому сравнение x.id_extra_tool === y.id_extra_tool всегда будет возвращать false, попробуйте изменить, чтобы использовать == вместо этого.

Короткий пример использования map:

 const mergedArray = this.extras.map(item => ({
  ...item,
  ...editedItem.extra_tools.find(i => i.id_extra_tool == item.id_extra_tool)
}));
  

Ответ №3:

Сначала я бы построил один массив в объект key / value, используя id_extra_tool в качестве ключа объекта, предполагая, что id_extra_tool всегда уникален. Это помогает повысить производительность.

Затем объедините со вторым массивом

 // build key/value object
obj = {};
editedItem.extra_tools.map((value) => {
  obj[value.id_extra_tool] = value;
});

// iterate other array and merge
const result = this.extras.map((extra) => {
  return Object.assign(obj[extra.id_extra_tool], extra);
});
  

 const extra_tools = [
{
    extra_tool_password: "tool data password",
    extra_tool_username: "tool data username",
    id_extra_tool: "8"
},
{
    extra_tool_password: "tool data password",
    extra_tool_username: "tool data username",
    id_extra_tool: "1"
},
{
    extra_tool_password: "tool data password",
    extra_tool_username: "tool data username",
    id_extra_tool: "7"
}
];


const extras = [
{
    extra_params: 1,
    extra_tool_name: "tool 1",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 1
},
{
    extra_params: 1,
    extra_tool_name: "tool 2",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 7
},
{
    extra_params: 0,
    extra_tool_name: "tool 3",
    extra_tool_password: "",
    extra_tool_username: "",
    id_extra_tool: 8
}
];

obj = {};
extra_tools.map((value) => {
obj[value.id_extra_tool] = value;
});

// iterate other array
const result = extras.map((extra) => {
return Object.assign(extra, obj[extra.id_extra_tool]);
});
console.log(result);