#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);