У меня есть два массива объектов, которые выглядят в формате JSON:
{
"Arr1":
[
{ "_id": "firstSub1", "count": 1, "price": 4 },
{ "_id": "firstSub2", "count": 2, "price": 7 },
{ "_id": "firstSub3", "count": 3, "price": 1 }
{ "_id": "firstSub4", "count": 4, "price": 1 }
],
"Arr2":
[
{ "name": "firstSub1", "date": 05 / 20 / 1998, "type": sometype1 },
{ "name": "firstSub2" "date": 12 / 22 / 2011, "type": sometype2 },
{ "name": "firstSub3", "date": 09 / 23 / 2004, "type": sometype3 }
{ "name": "firstSub9", "date": 09 / 23 / 2004, "type": sometype9 }
]
//Desired Output
"finalArray":
[
{ "name": "firstSub1", "date": 05 / 20 / 1998, "type": sometype1, "count": 1, "price": 4 },
{ "name": "firstSub2" "date": 12 / 22 / 2011, "type": sometype2, "count": 2, "price": 7 },
{ "name": "firstSub3", "date": 09 / 23 / 2004, "type": sometype3, "count": 3, "price": 1 },
{ "name": "firstSub9", "date": 09 / 23 / 2004, "type": sometype9 },
{ "_id": "firstSub4", "count": 4, "price": 1 }
]
}
Мне нужно сравнить _id в первом массиве и посмотреть, есть ли совпадение с name в Arr2, и сопоставить их, если _id === name.
Я пробовал использовать lodash и его аннулирование, а также такие функции отображения:
mergeArray() {
.... //pulling data
let Arr1 = data['Arr1Data'];
let Arr2 = data['Arr2Data'];
let finalArray = Arr2.map((e, _) =>
(_ = Arr1.find((q) => e.name === q._id)) ?
{ ...e, ..._ } : e)
console.info(finalArray)
}
Все данные из Arr2 возвращаются и объединяются только с половиной данных Arr1, мои данные не возвращаются с желаемым результатом... как я могу сопоставить эти два массива и получить объединение и пересечение?
Как? Я уже пробовал это .. и я получаю неопределенность, когда пытаюсь вызвать e.name
looks this in JSON format: Публикуя вопросы с примерами данных, постарайтесь сделать их достоверными, это поможет другим помочь вам.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Используя vanilla Js, вы можете получить массив уникальных _id и name из обоих массивов, прокрутить его и присоединиться к объекту из обоих массивов, который соответствует текущему id в итерации:
Дедуплицированный массив ids и names :
const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];
Цикл для соединения элементов из обоих массивов:
const result = ids.map(e => ({
...Arr1.find(o => o._id === e),
...Arr2.find(o => o.name === e)
}))
const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3, "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}];
const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}];
const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];
const result = ids.map(e => ({
...Arr2.find(o => o.name === e),
...Arr1.find(o => o._id === e)
}))
console.info(result)РЕДАКТИРОВАТЬ :
Вы можете настроить возвращенный объект в .map(), чтобы удалить свойства (например, _id):
const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3, "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}];
const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}];
const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];
const result = ids.map(e => {
const obj = {
...Arr2.find(o => o.name === e),
...Arr1.find(o => o._id === e)
}
if (obj.name && obj._id) delete obj._id;
return obj;
})
console.info(result)Отличный ответ Таки. Всего одна настройка, которую они хотят, чтобы _id был удален. Но тем не менее классно.
Хороший. что, если желаемый finalArray: ` "finalArray": [ { "name": "firstSub1", "date": 20/05/1998, "type": sometype1, "count": 1, "price": 4 } , { "имя": "firstSub2" "дата": 22 декабря 2011 г., "тип": какой-то тип2, "количество": 2, "цена": 7 }, { "имя": "firstSub3", "дата" : 23 09 2004, "тип": какой-то тип3, "количество": 3, "цена": 1 }, ` как будет использоваться функция удаления для массивов, для которых нет совпадений
Одним из решений является использование Массив.уменьшить(), начиная с accumulator, равного копии Arr2 (JSON.parse(JSON.stringify(Arr2))), чтобы не изменять исходный массив Arr2. Теперь, перебирая Arr1, если мы нашли совпадение, мы добавляем связанные свойства, используя Объект.назначить(), к связанному объекту в accumulator, в противном случае мы помещаем весь объект в accumulator:
const Arr1 = [
{"_id": "firstSub1", "count": 1, "price": 4},
{"_id": "firstSub2", "count": 2, "price": 7},
{"_id": "firstSub3", "count": 3, "price": 1},
{"_id": "firstSub4", "count": 4, "price": 1}
];
const Arr2 = [
{"name": "firstSub1", "date": "05/20/1998", "type": "sometype1"},
{"name": "firstSub2", "date": "12/22/2011", "type": "sometype2"},
{"name": "firstSub3", "date": "09/23/2004", "type": "sometype3"},
{"name": "firstSub9", "date": "09/23/2004", "type": "sometype9"}
];
let res = Arr1.reduce((acc, {_id, count, price}) =>
{
let fIdx = acc.findIndex(({name}) => name === _id);
if (fIdx >= 0)
Object.assign(acc[fIdx], {count, price});
else
acc.push({_id, count, price});
return acc;
}, JSON.parse(JSON.stringify(Arr2)));
console.info(res);.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}Вы можете отсортировать по name и сравнить имя индекса i + 1, чтобы проверить, следует ли объединить индекс i + 1 и индекс i или у объекта нет пары для слияния.
Например, сортировка по name означает, что следующим объектом/индексом будет пара.
[{name: "firstSub1", count: 1}, {name: "firstSub1", date: "dd / mm / yyyy"}] // Pair found
или
[{name: "firstSub1", count: 1}, {name: "firstSub2", count: 1}] // There is no a pair
Это при условии, что есть максимум одна пара
let obj = { "Arr1": [{ "_id": "firstSub1", "count": 1, "price": 4 }, { "_id": "firstSub2", "count": 2, "price": 7 }, { "_id": "firstSub3", "count": 3, "price": 1 }, { "_id": "firstSub4", "count": 4, "price": 1 } ], "Arr2": [{ "name": "firstSub1", "date": "05 / 20 / 1998", "type": "sometype1" }, { "name": "firstSub2", "date": "12 / 22 / 2011", "type": "sometype2" }, { "name": "firstSub3", "date": "09 / 23 / 2004", "type": "sometype3" }, { "name": "firstSub9", "date": "09 / 23 / 2004", "type": "sometype9" } ]};
// All objects in one array.
let merge = [...obj.Arr2,
// The map is to change _id by name, this is used later.
...obj.Arr1.map(({_id, count, price}) => ({name: _id, count, price}))]
.sort((a, b) => a.name.localeCompare(b.name));
// This approach doesn't mutate the source objects.
let result = [];
for (let i = 0; i < merge.length;) {
if (merge[i + 1] && merge[i + 1].name === merge[i].name) {
result.push(Object.assign(Object.create(null), merge[i], merge[i + 1]));
i++;
} else result.push(merge[i]);
i++;
}
console.info(result);.as-console-wrapper { max-height: 100% !important; top: 0; }Вы можете использовать _.flow() lodash для создания функции, которая объединяет массивы, группирует их по name или _id (в зависимости от того, что находится на объекте). Если группа содержит более 1 элемента, она объединяется в один объект, а свойство _id опускается.
const { flow, partialRight: pr, concat, groupBy, map, merge, has, head, omit } = _
const fn = flow(
concat, // combine to a single array
pr(groupBy, o => o.name || o._id), // group by the value of name or _id
pr(map, o => o.length === 1 ? head(o) : _.omit( // if a group contains 2 items merge them, and remove _id
merge({}, ...o),
'_id'
)),
)
const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3, "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}]
const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}]
const result = fn(Arr2, Arr1)
console.info(result)<script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>Следует отдать должное этому ответу. Я также использую его для объединения дубликатов в один массив. fn(Arr1) работает даже с одним аргументом.
Как насчет того, чтобы сначала объединить массивы, а затем использовать функцию .map с вашими пользовательскими сравнениями, чтобы заказать новый массив?