Comparing 2 objects' values and push the values to one object array - javascript

I am trying to compare 2 objects by their property and the values. If the value of the "name" property matches up with each other, I want to push the property and value to value3.
Once value3 is logged, I want the response like this:
{
name: 'dog',
surname: 'good',
skills: 'programming',
age: '22'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
age: '12'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
age: '23'
}
Here is the code:
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'
},
{
name: 'dog',
food: 'treats',
age: '22'
}
]
// push into this empty object array
var values3 = [{}]
console.log(values3)

const values1 = [
{ name: 'dog', surname: 'good', skills: 'programming' },
{ name: 'cat', surname: 'soft', skills: 'engineer' },
{ name: 'elephant', surname: 'big', skills: 'programming' }
]
const values2 = [
{ name: 'cat', food: 'fish', age: '12' },
{ name: 'elephant', food: 'leafs', age: '13' },
{ name: 'dog', food: 'treats', age: '22' }
]
const values3 = values1.map((value1) => {
return Object.assign(value1, { age: values2.filter(value2 => value2.name === value1.name)[0].age })
})
console.log(values3)
The code above will only work if for each name in values1 an object with name exists in values2. If not use this code:
const values3 = values1.map((value1) => {
const found = values2.find(value2 => value2.name === value1.name)
return Object.assign(value1, { age: found ? found.age : undefined })
})

Related

Push multiple objects to an already initialized, empty object array

People is my model, data is my new information, and the forEach is how I am trying to insert the new data into my model, but formatted to only the information I care about
people = [{name: '', age: 0}];
data = [
{id: '123', name: 'Bob', lastName: 'Guy', age: 40},
{id: '321', name: 'Michael', lastName: 'Park', age: 20},
]
data.forEach(person => {
people.push({
name: person.name,
age: person.age,
});
});
However, the result I get is this:
people = [
{name: '', age: 0},
{name: 'Bob', age: 40},
{name: 'Michael', age: 20}
];
I'm trying to have the object array look like this instead:
people = [
{name: 'Bob', age: 40},
{name: 'Michael', age: 20}
];
However, I would like to know if theres a way to do it without an extra line of code (like popping the first element), and if theres a way to do it in one command? If not, I am open to suggestions. Thank you!
You're using the original array and not only that but also you're mutating the array.
You can use the function Array.prototype.map in order to generate a new array with the desired data.
const people = [{name: '', age: 0}];
const data = [
{id: '123', name: 'Bob', lastName: 'Guy', age: 40},
{id: '321', name: 'Michael', lastName: 'Park', age: 20},
]
const result = data.map(person => ({
name: person.name,
age: person.age,
}));
console.log(result);
You can also keep the desired keys and by using the functions Array.prototype.map and Array.prototype.reduce you can build the expected result:
const model = ["name", "age"];
const data = [
{id: '123', name: 'Bob', lastName: 'Guy', age: 40},
{id: '321', name: 'Michael', lastName: 'Park', age: 20},
]
const result = data.map(person => model.reduce((r, m) => ({...r, [m]: person[m]}), {}), []);
console.log(result);
Just in case you need to implement different person models, you can dinamically create the objects like this
peopleModel = [{ name: "", age: 0 }];
data = [
{ id: "123", name: "Bob", lastName: "Guy", age: 40 },
{ id: "321", name: "Michael", lastName: "Park", age: 20 },
];
const keysArr = Object.keys(peopleModel[0]);
const totalKeys = keysArr.length;
const people = data.reduce((acc, personObj) => {
const obj = {};
keysArr.forEach((key) => {
if (personObj[key]) {
obj[key] = personObj[key];
}
});
acc.push(obj);
return acc;
}, []);
console.log(people);
/* logs [
{name: 'Bob', age: 40},
{name: 'Michael', age: 20}
];
*/
but if you need a different model like
peopleModel = [{ name: "", age: 0, lastName: "" }]
you will get for the log the following:
[
{name: 'Bob', age: 40, lastName: 'Guy'},
{name: 'Michael', age: 20, lastName: 'Park'}
];
that way you do not need to hardcode the keys

How to compare the sameness of object entries of 2 arrays and how to create a merger of both objects with custom properties of the found same object?

I am trying to compare 2 objects by their property and the values Strictly using forloop. If the value of the "name" or another property matches up with each other, I want to push the property and value to value3.
Once value3 is logged, I want the response like this:
{
name: 'dog',
surname: 'good',
skills: 'programming',
age: '22'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
age: '12'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
age: '23'
}
Here is the code:
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)
The most generic approach which fulfills all of the OP's requirements should be based on Array.prototype.reduce. Its advantage comes with utilizing the additionally passed optional initial value as kind of configurable collector/accumulator object which will carry all the needed additional information / functions / result. Thus one can provide a reusable function with a customizable context/environment which one can adapt to ones needs.
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; }
If you just want the key and value pair, you can do something like this:
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] &&
eachValue2Obj[eachKey] &&
eachValue1Obj[eachKey] === eachValue2Obj[eachKey]
) {
const x = {
key: eachKey,
value: eachValue1Obj[eachKey]
};
values3.push(x)
}
})
})
})
console.log('Values 3 Array ==>', values3);

How to compare the property of object entries of 2 length arrays and merge into one? [duplicate]

This question already has answers here:
Filter array of objects with another array of objects
(11 answers)
Closed 1 year ago.
I am trying to compare values1 and values2 by their property and the values. If the value of the name property matches up with each other, I want to push the property and value to value3.
But I am getting this error: Cannot read property 'age' of undefined
const values1 = [
{ name: 'dog', surname: 'good', skills: 'programming' },
{ name: 'cat', surname: 'soft', skills: 'engineer' },
{ name: 'elephant', surname: 'big', skills: 'programming' }
]
const values2 = [
{ name: 'cat', age: '12' },
{ name: 'elephant', age: '13' },
]
const values3 = values1.map((value1) => {
return Object.assign(value1, { age: values2.filter(value2 => value2.name === value1.name)[0].age })
})
console.log(values3)
This is the result I would like to return.
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
age: '12'
},
{
name: 'dog',
surname: 'good',
skills: 'programming',
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
age: '23'
}
You can do it like this:
const values1 = [{
name: 'dog',
surname: 'good',
skills: 'programming'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
}
]
const values2 = [{
name: 'cat',
age: '12'
},
{
name: 'elephant',
age: '13'
},
]
const values3 = values1.map((value1) => {
const sameObj = values2.find(value2 => value2.name === value1.name);
if (sameObj) {
return { ...value1, age: sameObj.age }
}
return value1;
});
console.log(values3)

Frequency Counter in array of objects for certain key

I have an array of objects with students name which are getting repeated often. I want to create a frequency counter of the students name with the number of total counts.
Array :
arr = [
{
name: 'Akshay',
age: '15',
},
{
name: 'Rajat',
age: '14',
},
{
name: 'Akshay',
age: '16',
},
{
name: 'Sam',
age: '12',
},
{
name: 'Akshay',
age: '11',
},
{
name: 'Rajat',
age: '17',
},
{
name: 'Akshay',
age: '12',
},
{
name: 'Sam',
age: '18',
},
{
name: 'Sam',
age: '19',
}
]
I want to get the result like this in an array
result = [
{
name: 'Akshay',
count: 4
},
{
name: 'Rajat',
count: 2
},
{
name: 'Sam',
count: 3
},
]
I tried the below solution but it's not working properly -
const result = arr.reduce((counter,item) => {
var getItem = item.name;
counter[getItem] = counter.hasOwnProperty(getItem) ? counter[getItem] : 1;
return counter;
})
Please help.
You need to pass an accumulator in the reduce. In this case pass an empty object as an accumulator , so the accumulator will look like
{
name:{
name:someName,
count:someCount
},
name2:{
name:someName,
count:someCount
}
}
Once the accumulator is successfully populated, then use Object.values to get an array
const arr = [{
name: 'Akshay',
age: '15',
},
{
name: 'Rajat',
age: '14',
},
{
name: 'Akshay',
age: '16',
},
{
name: 'Sam',
age: '12',
},
{
name: 'Akshay',
age: '11',
},
{
name: 'Rajat',
age: '17',
},
{
name: 'Akshay',
age: '12',
},
{
name: 'Sam',
age: '18',
},
{
name: 'Sam',
age: '19',
}
]
const result = arr.reduce((counter, item) => {
var getItem = item.name;
if (counter.hasOwnProperty(getItem)) {
counter[getItem].count += 1;
} else {
counter[getItem] = {
name: getItem,
count: 1
};
}
return counter;
}, {});
console.log(Object.values(result))
Try this: (you have been missing the initial value)
const count = arr.reduce((prev, cur) => {
prev[cur.name] = (prev[cur.name] || 0) + 1;
return prev;
}, {});
console.log(count);

How to filter an Array of Objects inside another Array of Objects in JavaScript (es6)? [duplicate]

This question already has answers here:
Filter array of objects with another array of objects
(11 answers)
Closed 2 years ago.
I need to filter dogs and also the sitters inside this Array based on another Array sittersSelected. (It's ok to use es6). The problem for me is handling the nested array.
Not sure if it's possible but...
Data
dogs = [
{
name: 'Alice',
sex: 'Female',
breed: 'German Shepherd',
sitters: [
{
id: '123',
name: 'Abby'
},
{
id: '456',
name: 'Manny'
},
{
id: '789',
name: 'Mel'
},
]
},
{
name: 'Buckley',
sex: 'Male',
breed: 'Border Collie',
sitters: [
{
id: '321',
name: 'Gustavo'
},
{
id: '654',
name: 'Tommy'
},
]
},
{
name: 'Bear',
sex: 'Male',
breed: 'Mixed',
sitters: [
{
id: '123',
name: 'Abby'
},
{
id: '135',
name: 'Owen'
},
]
},
];
sittersSelected = ["Abby","Manny"];
Expected Output
filterResult = [
{
name: 'Alice',
sex: 'Female',
breed: 'German Shepherd',
sitters: [
{
id: '123',
name: 'Abby'
},
{
id: '456',
name: 'Manny'
},
]
},
{
name: 'Bear',
sex: 'Male',
breed: 'Mixed',
sitters: [
{
id: '123',
name: 'Abby'
},
]
},
];
I've tried
filterResult = dogs.filter(dog => dog.sitters.some(sitter => sittersSelected.includes(sitter.name)));
I managed to filter the dogs but not the sitters. Also tried other examples here on StackOverflow. Is there a way to do it? maybe with .map() ?
Thank you
1-use map to return new object contain only filtered sitters
2-use filter to return only dog have sitters
let dogs = [{ name: 'Alice', sex: 'Female', breed: 'German Shepherd', sitters: [{ id: '123', name: 'Abby' }, { id: '456', name: 'Manny' }, { id: '789', name: 'Mel' },] }, { name: 'Buckley', sex: 'Male', breed: 'Border Collie', sitters: [{ id: '321', name: 'Gustavo' }, { id: '654', name: 'Tommy' },] }, { name: 'Bear', sex: 'Male', breed: 'Mixed', sitters: [{ id: '123', name: 'Abby' }, { id: '135', name: 'Owen' },] },];
let sittersSelected = ["Abby", "Manny"];
dogs.map(dog => {
return {
...dog,
sitters: dog.sitters.filter(sitter => sittersSelected.includes(sitter.name))
}
}).filter(dog => dog.sitters.length > 0);
You'll need 2 steps.
First filter each sitters sub-array to include only the ones selected.
Filter out the parent array items by whether the sitters array contains any elements:
const dogs=[{name:"Alice",sex:"Female",breed:"German Shepherd",sitters:[{id:"123",name:"Abby"},{id:"456",name:"Manny"},{id:"789",name:"Mel"}]},{name:"Buckley",sex:"Male",breed:"Border Collie",sitters:[{id:"321",name:"Gustavo"},{id:"654",name:"Tommy"}]},{name:"Bear",sex:"Male",breed:"Mixed",sitters:[{id:"123",name:"Abby"},{id:"135",name:"Owen"}]}];
const sittersSelected = ["Abby","Manny"];
for (const dog of dogs) {
dog.sitters = dog.sitters.filter(s => sittersSelected.includes(s.name));
}
const filteredDogs = dogs.filter(
dog => dog.sitters.length
);
console.log(filteredDogs);
If you don't want to mutate the input array of objects, you can map it first to clone each dog.

Categories