#javascript #arrays #object #merge #comparison
#javascript #массивы #объект #слияние #сравнение
Вопрос:
Я пытаюсь сравнить 2 объекта по их свойству и значениям, строго используя forloop. Если значение «name» или другого свойства совпадает друг с другом, я хочу перевести свойство и значение в значение3.
После регистрации значения3 я хочу, чтобы ответ был таким:
{
name: 'dog',
surname: 'good',
skills: 'programming',
age: '22'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
age: '12'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
age: '23'
}
Вот код:
var values1 = [
{
name: 'dog',
surname: 'good',
skills: 'programming'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
}
]
var values2 = [
{
name: 'cat',
food: 'fish',
age: '12'
},
{
name: 'elephant',
food: 'leafs',
age: '13'
},
{
lastname: 'dog',
food: 'treats',
age: '22'
}
]
// push into this empty object array
var values3 = [{}]
console.log(values3)
Комментарии:
1. … разве это не должно быть
age: 13
для нужногоname: 'elephant'
элемента? И по какому правилу происходитage
слияние с конечным элементом, ноfood
не происходит? И почему этоlastname: 'dog'
дляvalues2
последнего элемента?2. не беспокойтесь о
food
том, что я просто хочу сравнитьname:
из массивов, и если они совпадают, то нажмитеage
на это. но мы видим, что существует такжеlastname:
свойство, но оно по-прежнему имеет то же значение, что иname
3. Как следует предоставить OP действительный общий подход, если вопрос / требования и даже пример кода представлены не так точно? Например, Q. указывает явно… «Если значение «name» или другого свойства совпадает друг с другом» … но затем OP изменяет его в дополнительном комментарии на … «не беспокойтесь о
food
том, что я просто хочу сравнитьname
» . Пожалуйста, OP переработайте свой вопрос и укажите точные требования.4. потому что, если вы посмотрите на свойства обоих, вы увидите, что
food
этого нет в обоих массивах. Все, что я прошу, это сравнить значения и, если они совпадают, поместить все свойства и значения в один новый массив5.
age
too не является частью элементов каждого массива, но он объединяется. Снова. Укажите точные требования.
Ответ №1:
Наиболее общий подход, который удовлетворяет всем требованиям OP, должен основываться на Array.prototype.reduce
. Его преимущество заключается в использовании дополнительно переданного необязательного начального значения в качестве настраиваемого объекта коллектора / аккумулятора, который будет содержать всю необходимую дополнительную информацию / функции / результат. Таким образом, можно предоставить повторно используемую функцию с настраиваемым контекстом / средой, которую можно адаптировать к своим потребностям.
var values1 = [{
name: 'dog',
surname: 'good',
skills: 'programming',
}, {
name: 'cat',
surname: 'soft',
skills: 'engineer',
}, {
name: 'elephant',
surname: 'big',
skills: 'programming',
}];
var values2 = [{
name: 'cat',
food: 'fish',
age: '12'
}, {
name: 'elephant',
food: 'leafs',
age: '13'
}, {
lastname: 'dog',
food: 'treats',
age: '22'
}];
function mergeItemsOfSameEntry(collector, item) {
const {
getSameEntryValue,
getMergeSubType,
comparisonItems,
result
} = collector;
const itemValue = getSameEntryValue(item);
const comparisonItem = comparisonItems
.find(cItem => getSameEntryValue(cItem) === itemValue);
if (comparisonItem !== null) {
result.push({
...item,
...getMergeSubType(comparisonItem),
});
}
return collector;
}
const values3 = values1.reduce(mergeItemsOfSameEntry, {
getSameEntryValue: item => item.name ?? item.lastname,
getMergeSubType: ({ age }) => ({ age }),
comparisonItems: values2,
result: [],
}).result;
console.log({ values3 });
.as-console-wrapper { min-height: 100%!important; top: 0; }
Ответ №2:
Если вам просто нужна пара ключ и значение, вы можете сделать что-то вроде этого:
var values1 = [
{
name: 'dog',
surname: 'good',
skills: 'programming'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
}
]
var values2 = [
{
name: 'cat',
food: 'fish',
age: '12'
},
{
name: 'elephant',
food: 'leafs',
age: '13'
},
{
lastname: 'dog',
food: 'treats',
age: '22'
}
]
// push into this empty object array
var values3 = [];
values1.forEach(eachValue1Obj => {
const keys = Object.keys(eachValue1Obj);
keys.forEach(eachKey => {
values2.forEach(eachValue2Obj => {
if (
eachValue1Obj[eachKey] amp;amp;
eachValue2Obj[eachKey] amp;amp;
eachValue1Obj[eachKey] === eachValue2Obj[eachKey]
) {
const x = {
key: eachKey,
value: eachValue1Obj[eachKey]
};
values3.push(x)
}
})
})
})
console.log('Values 3 Array ==>', values3);
Комментарии:
1. это немного похоже на то, что я спрашиваю. Я хочу, чтобы ответ values3 был
{ name: 'dog', surname: 'good', skills: 'programming', age: '22' }, { name: 'cat', surname: 'soft', skills: 'engineer' age: '12' }, { name: 'elephant', surname: 'big', skills: 'programming' age: '23' }
2. Без дальнейшего анализа кода и, кроме того, результат не близок к тому, о чем просил OP, я хочу упомянуть, что, на мой взгляд, подход с 3 вложенными
forEach
циклами уже движется в неправильном направлении.