Push multiple objects to an already initialized, empty object array - javascript

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

Related

Javascript filter array object inside non-array object

I have an object like this:
var obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}, {name: 'Richard', age: '33'}]}
I tried to filter the object to show only the author with age above 35. This is what I expected:
var obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}]}
However since the array is inside a non-array object, I cannot use filter() yet. How to approach this?
This is helpful in case you have more than one variable that keeps the same:
var obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}, {name: 'Richard', age: '33'}]}
obj = {
...obj,
author: obj.author.filter( x => x.age >= 35)
}
console.log(obj)
Although I recommend keeping the original obj and create a new one for the filtered obj:
var obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}, {name: 'Richard', age: '33'}]}
const above35 = {
...obj,
author: obj.author.filter( x => x.age >= 35)
}
console.log(obj,"and",above35)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
obj.author = obj.author.filter(checkAge); // this will return an array with 1 object.
function checkAge(author) {
return author.age >= 35;
}
One simple way would be like this:
var obj = {
name: "Lesson I",
author: [
{ name: "Thomas", age: "40" },
{ name: "Richard", age: "33" },
],
};
const result = obj.author.filter((ob) => ob.age > 35);
obj.author = result;
console.log(obj);
One way...declare a new object with each key/value of the original object, but filter() the author value:
let obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}, {name: 'Richard', age: '33'}]};
let obj_old_authors = {
name: obj.name,
author: obj.author.filter(author => 35 < author.age)
};
console.log(obj_old_authors);

JavaScript ungroup data in object

I am trying to flatten the below data structure, I feel like there must be a good way fo doing this without manually iterating through each element to manually build it.
[{
group: 'abc',
data: [{
name: 'John',
age: 10
}, {
name: 'Alice',
age: 15
}]
}, {
group: 'def',
data: [{
name: 'Scott',
age: 20
}, {
name: 'Tamar',
age: 25
}]
}]
and I wanted it to be something like this instead (so the group is alongside the data):
[{
group: 'abc',
name: 'John',
age: 10
}, {
group: 'abc',
name: 'Alice',
age: 15
}, {
group: 'def',
name: 'Scott',
age: 20
}, {
group: 'def',
name: 'Tamar',
age: 25
}]
Any ideas would be appreciated.
const a = [
{group: 'abc', data: [{name: 'John', age: 10}, {name: 'Alice', age: 15}]},
{group: 'def', data: [{name: 'Scott', age: 20}, {name: 'Tamar', age: 25}]}
];
const flat = a.flatMap(({group, data}) => data.map(o => Object.assign({group}, o)));
console.log(flat)
// Unmodified original Array:
console.log(a)
MDN Array.prototype.flatMap()
MDN Array.prototype.map()
MDN Object.assign()
Array#reduce would be helpful.
const a = [{group:'abc',data:[{name:'John',age:10},{name:'Alice',age:15}]},{group:'def',data:[{name:'Scott',age:20},{name:'Tamar',age:25}]}];
const r = a.reduce((s, { group, data }) =>
(data.forEach((o) => s.push({ ...o, group })), s), []);
console.log(r);
Iterate the array with Array.flatMap(), then map each group, and construct the new objects using object spread:
const arr = [{"group":"abc","data":[{"name":"John","age":10},{"name":"Alice","age":15}]},{"group":"def","data":[{"name":"Scott","age":20},{"name":"Tamar","age":25}]}]
const result = arr.flatMap(({ group, data }) => data.map(o => ({ group, ...o })))
console.log(result)

Keep only selected keys in every object from array [duplicate]

This question already has answers here:
How to get a subset of a javascript object's properties
(36 answers)
Closed 12 months ago.
EDIT: not a duplicate, as my question does not ask for deleting a specific key, but all keys not found in an array.
In the below, function redux1 removes entries corresponding to keys not listed in keys_to_keep from data object.
Given that I have a list of object keys to keep, how can I rewrite redux1 in a cleaner way, prefarably utilizing map, filter or reduce?
var data = [
{name: 'John', city: 'London', age: 42},
{name: 'Mike', city: 'Warsaw', age: 18},
{name: 'Jim', city: 'New York', age: 22},
{name: 'Celine', city: 'Tokyo', age: 54},
]
var keys_to_keep = ['name', 'city']
function redux1(data) {
data.forEach((person) => {
Object.keys(person).forEach((key) => {
if (!keys_to_keep.includes(key)) {
delete (person[key])
}
})
})
console.log(data)
}
function redux2(data) {
var reduced = data.filter(person => Object.keys(person).filter(key => keys_to_keep.includes(key)))
console.log(reduced)
}
redux1(data)
//redux2(data)
My current redux2 will return objects will not remove age.
You could use a combination of Array#map and Array#reduce:
const data = [
{name: 'John', city: 'London', age: 42},
{name: 'Mike', city: 'Warsaw', age: 18},
{name: 'Jim', city: 'New York', age: 22},
{name: 'Celine', city: 'Tokyo', age: 54},
]
const keys_to_keep = ['name', 'city'];
const redux = array => array.map(o => keys_to_keep.reduce((acc, curr) => {
acc[curr] = o[curr];
return acc;
}, {}));
console.log(redux(data));
A version slightly shorter than the accepted answer using Array#map and Object.fromEntries():
const data = [
{name: 'John', city: 'London', age: 42},
{name: 'Mike', city: 'Warsaw', age: 18},
{name: 'Jim', city: 'New York', age: 22},
{name: 'Celine', city: 'Tokyo', age: 54},
]
const keys_to_keep = ['name', 'city'];
const redux1 = list => list.map(o => Object.fromEntries(
keys_to_keep.map(k => [k, o[k]])
));
console.log(redux1(data));
use Array.map and Array.forEach inside it :
var data = [
{name: 'John', city: 'London', age: 42},
{name: 'Mike', city: 'Warsaw', age: 18},
{name: 'Jim', city: 'New York', age: 22},
{name: 'Celine', city: 'Tokyo', age: 54},
]
var keys_to_keep = ['name', 'city']
const result = data.map(e => {
const obj = {};
keys_to_keep.forEach(k => obj[k] = e[k])
return obj;
});
console.log(result);
var data = [
{name: 'John', city: 'London', age: 42},
{name: 'Mike', city: 'Warsaw', age: 18},
{name: 'Jim', city: 'New York', age: 22},
{name: 'Celine', city: 'Tokyo', age: 54},
]
var keys_to_keep = ['name', 'city']
data=data.map(element => Object.assign({}, ...keys_to_keep.map(key => ({[key]: element[key]}))))
console.log(data)
data.reduce((r, c) => [ ...r, Object.entries(c).reduce((b, [k, v]) => keys_to_keep.includes(k) ? {...b, [k]: v } : b, {}) ],[])
You can use Object.entries
function objfilter(data,keys_to_keep){
return Object.fromEntries(Object.entries(data).filter(a=>keys_to_keep.includes(a[0])))
}
const data = [
{name: 'John', city: 'London', age: 42},
{name: 'Mike', city: 'Warsaw', age: 18},
{name: 'Jim', city: 'New York', age: 22},
{name: 'Celine', city: 'Tokyo', age: 54},
]
const keys_to_keep = ['name', 'city'];
console.log(objfilter(data,keys_to_keep))

Mapping data from two arrays which have different lengths and creating another array

I have two arrays which have two different lengths.
For example:
var array1 = [{name: 'Yuri', age: 2, gender: 'Male'}, {name: 'Akit', age: 19, gender: 'Male'}, {name: 'Kean', age: 14, gender: 'Female'}, {name: 'Jan', age: 29, gender: 'Male'}, {name: 'Max', age: 25, gender: 'Male'}, {name: 'Suzy', age: 20, gender: 'Female'}];
var array2 = [{name: 'Jan', gender: 'Male', occupation: 'Designer'}, {name: 'Max', gender: 'Male', occupation: 'Developer'}, {name: 'Suzy', gender: 'Female', occupation: 'Tester'}];
array1's length is 5 and array2's length is 3. I want to run a loop on both arrays and match the name. If the name matches then I want to extract the that particular object from 2nd array. As they have different lengths loop is breaking at the first array length and not reaching 2nd array's last element. I am running the for loop based on array2 length. Please help me with this.
Expected result:
Name of both arrays should be matched and create another array as below
var array3 = [{name: 'Jan',age: 29, gender: 'Male', occupation: 'Designer'},
same for other objects]
You could take a Set for one array's names and filter the second array.
var array1 = [{name: 'Yuri', age: 9, gender: 'Male'}, {name: 'Akit', age: 19, gender: 'Male'}, {name: 'Kean', age: 14, gender: 'Female'}, {name: 'Jan', gender: 'Male'}, {name: 'Max', gender: 'Female'}],
array2 = [{name: 'Jan', age: 9, gender: 'Male'}, {name: 'Max', age: 19, gender: 'Male'}, {name: 'Suzy', age: 14, gender: 'Female'}],
set2 = new Set(array2.map(({ name }) => name)),
result = array1.filter(o => set2.has(o.name));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var arr1 = [{name: 'Jan', age: 19}, {name: 'Suzy', age: 29}, {name: 'Peter', age: 39}, {name: 'Bart', age: 49}, {name: 'John', age: 59}];
var arr2 = [{name:'Kean', job: 'Technician'},{name:'Nick', job:'Mathematics'},{name: 'Jan', job: 'Tester'}, {name: 'Suzy', job:'Developer'}, {name: 'Peter', job: 'Scrum master'}];
result = arr1.map(x=> {
y = arr2.find(z=> x.name == z.name);
x.job = y ? y.job : undefined;
return x;
});

How to find all matching keys and values of one object in array of objects?

I need a code which would loop through an array of objects and check if keys and values match with ones in a separate object, and then push object that contains all keys and values in a new array, so for a specific case:
var arr = [{name: 'john', lastname: 'roberts', children: 3},
{name: 'john', lastname: 'green', children: null},
{name: 'steve', lastname: 'baker', children: 3}];
var obj = {name: 'john', children: 3};
result would be:
arr2 = [{name: 'john', lastname: 'roberts', children: 3}];
expanding #Psidom version
var arr = [{name: 'john', lastname: 'roberts', children: 3},
{name: 'john', lastname: 'green', children: null},
{name: 'steve', lastname: 'baker', children: 3}];
var obj = {name: 'john', children: 3};
console.log(
arr.filter(x => Object.keys(obj).every( k => x[k] == obj[k]))
);
Use filter on the Array:
var arr = [{name: 'john', lastname: 'roberts', children: 3},
{name: 'john', lastname: 'green', children: null},
{name: 'steve', lastname: 'baker', children: 3}];
var obj = {name: 'john', children: 3};
console.log(
arr.filter(x => x.name === obj.name && x.children === obj.children)
);

Categories