Как найти значение массива внутри другого массива, а затем соответствующим образом установить данные?

#javascript #arrays #reactjs #object #filter

#javascript #массивы #reactjs #объект #Фильтр

Вопрос:

У меня есть этот первый массив:

 const arrayOne = [
    {number: "DS5.11", name: "nameOne"},
    {number: "DS5.11", name: "nameTwo"},
    {number: "D5.10", name: "NameThree"}
]
  

Тогда у меня есть этот второй массив. Аналогично первому:

 const arrayOne = [
    {number: "DS5.11", name: "nameFour"},
    {number: "DS5.85", name: "nameFive"},
    {number: "D5SA1", name: "NameSix"}
]
  

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

Что-то вроде:

 let arrayThree = []
arrayOne.filter((e,i) => {
    arrayTwo.map((obj,idx) => { if(obj.number === e.number) {
        arrayThree[i] = {key: value}
    }})
})
  

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

Что я делаю не так? Заранее спасибо.

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

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

2. map и filter возвращают новые массивы. Вы хотите включить в выходные данные объединение / пересечение двух массивов? Пожалуйста, включите пример ожидаемого результата.

Ответ №1:

Я не знаю, правильно ли я понял, но вот мое решение:

 arrayOne.filter(obj1 => {

    
    for (obj2 of arrayTwo) {
        if (obj1.number === obj2.number) {
            arrayThree.push({ key: obj1.number });
            return false; 
        } else {
            return true;
        }
    }
    
});
  

Этот метод фильтрует значения arrayOne и сохраняет повторяющиеся числа внутри arrayThree.
arrayTwo остается нетронутым.

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

1. Это решение сработало отлично. Тот, что с Lodash, тоже сделал, но я бы предпочел сделать это без внешней библиотеки. Спасибо!

Ответ №2:

Если вы используете Lodash, следующий код должен работать

   const arrayOne = [
        {number: "DS5.11", name: "nameOne"},
        {number: "DS5.11", name: "nameTwo"},
        {number: "D5.10", name: "NameThree"}
    ]

    const arrayTwo = [
        {number: "DS5.11", name: "nameFour"},
        {number: "DS5.85", name: "nameFive"},
        {number: "D5SA1", name: "NameSix"}
    ]

    console.log(_.intersectionBy(arrayOne,arrayTwo,"number"))
  

Ответ №3:

если вы хотите сохранить name свойство arrayOne, то

 let arrayThree = [];
arrayOne.filter((e,i) => {
    arrayTwo.map((obj,idx) => { if(obj.number === e.number) {
        arrayThree[i] = e;
    }})
})
  

аналогично, чтобы сохранить name свойство arrayTwo

 let arrayThree = [];
arrayOne.filter((e,i) => {
    arrayTwo.map((obj,idx) => { if(obj.number === e.number) {
        arrayThree[i] = obj;
    }})
})
  

Ответ №4:

Создайте сопоставление числа с массивом элементов, используя array 1

 const intersectionMap = arrayOne.reduce(
  (obj, el) => {
    if (!obj[el.number]) obj[el.number] = [];
    obj[el.number].push(el)
    return obj;
  },
  {}
);
  

Выполните итерацию по массиву 2 и, если карта пересечений имеет ключ, вставьте элемент в массив

 arrayTwo.forEach(el => obj[el.number]?.push(el));
  

Отфильтруйте массивы длиной 1 и сгладьте результирующие массивы

 const res = Object.values(obj).flatMap(arr => arr.length > 1 ? arr : []);
  

Нет вложенных циклов, поэтому O(n) сложность времени выполнения.

 const arrayOne = [
  { number: "DS5.11", name: "nameOne" },
  { number: "DS5.11", name: "nameTwo" },
  { number: "D5.10", name: "NameThree" }
];

const arrayTwo = [
  { number: "DS5.11", name: "nameFour" },
  { number: "DS5.85", name: "nameFive" },
  { number: "D5SA1", name: "NameSix" }
];

const intersectionMap = arrayOne.reduce(
  (obj, el) => {
    if (!obj[el.number]) obj[el.number] = [];
    obj[el.number].push(el)
    return obj;
  },
  {}
);

arrayTwo.forEach(el => intersectionMap[el.number]?.push(el));

const res = Object.values(intersectionMap).flatMap(arr => arr.length > 1 ? arr : []);

console.log(res);