How do I search and iterate this object for an id? - javascript

I have an object where the values are arrays and they've further objects inside them like this:
let primaryStandard = {
section1: [{name: 'andy', id: 1}, {name: 'charles', id: 2},...],
section2: [{name: 'megan', id: 55}, {name: 'derek', id: 56},...],
section3: [{name: 'robert', id: 95}, {name: 'nathan', id: 96},...],
}
Basically, I want to iterate this whole object for a particular id value and then get the name and section in an object.
Example:
For id = 95 the result should be {section: section3, name: 'robert`}
What I've tried so far:
let primaryStandard = {
section1: [{name: 'andy', id: 1}, {name: 'charles', id: 2}],
section2: [{name: 'megan', id: 55}, {name: 'derek', id: 56}],
section3: [{name: 'robert', id: 95}, {name: 'nathan', id: 96}],
}
for (let key of Object.keys(primaryStandard)) {
console.log((primaryStandard[key])) // logs the values(array)
primaryStandard[key].map(student => console.log(student)) // .map() is not defined error
}

You could do this using find method on Object.keys to get section and name.
let data = {section1: [{name: 'andy', id: 1}, {name: 'charles', id: 2}],section2: [{name: 'megan', id: 55}, {name: 'derek', id: 56}],section3: [{name: 'robert', id: 95}, {name: 'nathan', id: 96}],}
let name;
let section = Object.keys(data).find(key => {
const match = data[key].find(({id}) => id == 95);
if(match) return name = match.name
})
console.log({name, section})

Related

How to create object fields dynamically based on values in Javascript?

I have an object array like this:
const values = [{name: 'name1', index: 1}, {name: 'name2', index: 2}, {name: 'name3', index: 3}]
Is it possible to create such an object dynamically?
const result = {
name1: 1,
name2: 2,
name3: 3
}
what you can do is the following!
const values = [{name: 'name1', index: 1}, {name: 'name2', index: 2}, {name: 'name3', index: 3}];
const result = {};
values.forEach(value => result[value.name] = value.index);
console.log(result); // {name1: 1, name2: 2, name3: 3}

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 group array of objects by certain property values

I have a two arrays.
One array with strings which contains names
let companies = ['Google', 'Coca Cola,' 'Jonson & Jonson',];
And another array contains objects with people
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
And my task is to group those people by names
const groups = [
{'Google': [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vlad' company: 'Google', id : 4},
]},
'Jonson & Jonso': [
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
]},
...
]
Maybe anyone knows how to do it the simplest way and without extra iterations for JS ?
I could use a nested loops but it would be too complicated.
Maybe it's possible to do with lodash ?
Also please note that string keys for company names may have spaces.
Will be very grateful for any advices.
A back to the future answer :
Not yet supported by lot of browsers but will come soon (Stage 3 for TC39) and already available in polyfill core-js) is the new groupBy method on the array object.
This will allows you to do it directly like this :
employees.groupBy(employee => employee.company);
or even :
employees.groupBy(({company}) => company);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/groupBy
let employees = [
{name: 'Alina', company: 'Google', id : 1},
{name: 'Vika', company: 'Coca Cola', id : 2},
{name: 'Alex', company: 'Jonson & Jonson', id : 3},
{name: 'Vlad', company: 'Google', id : 4},
{name: 'Fibi', company: 'Coca Cola', id : 5},
{name: 'Joey', company: 'Google', id : 6},
]
function groupBy(arr, property) {
return arr.reduce(function (memo, x) {
if (!memo[x[property]]) { memo[x[property]] = []; }
memo[x[property]].push(x);
return memo;
}, {});
};
console.log(groupBy(employees,'company'));
The simplest way would be:
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
const grouped = groupBy(employees, employee => employee.company);
Mate, it seems like no respect for potential responders, if u don't even check if ur structures are free of errors, before asking a question. Nvm :/
So, there are fixed variables:
let companies = ['Google', 'Coca Cola', 'Jonson & Jonson'];
let employees = [
{name: 'Alina', company: 'Google', id : 1},
{name: 'Vika', company: 'Coca Cola', id : 2},
{name: 'Alex', company: 'Jonson & Jonson', id : 3},
{name: 'Vlad', company: 'Google', id : 4},
{name: 'Fibi', company: 'Coca Cola', id : 5},
{name: 'Joey', company: 'Google', id : 6}]
Please notice that companies is redundant, as all the needed info is in employees.
The structure that you are looking for is probably Map. You simply do:
let map = new Map()
employees.forEach((currentValue) => {
map.has(currentValue.company)
? map.get(currentValue.company).push({name: currentValue.name, id: currentValue.id})
: map.set(currentValue.company, [{name: currentValue.name, id: currentValue.id}])
});
to get this result (field company won't be needed anymore in employee object):
{
Coca Cola: [{
id: 2,
name: "Vika"
}, {
id: 5,
name: "Fibi"
}],
Google: [{
id: 1,
name: "Alina"
}, {
id: 4,
name: "Vlad"
}, {
id: 6,
name: "Joey"
}],
Jonson & Jonson: [{
id: 3,
name: "Alex"
}]
}
Since you are going the simple route it would be slightly long.
let companies = ['Google', 'Coca Cola,' 'Jonson & Jonson',];
let employees = [
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Fibi' company: 'Coca Cola', id : 5},
{name: 'Joey' company: 'Google', id : 6},
]
//Let's create an intermediate object
let interm = {};
/*This would create an object like
{
Key:[],
Key2:[],
...
}
*/
companies.forEach((each)=>{
interm[`${each}`] = [];
})
/*filling that interm a
Object with values like
{
'Google':[
{name: 'Alina' company: 'Google', id : 1},
{name: 'Vlad' company: 'Google', id : 4},
{name: 'Joey' company: 'Google', id : 6}
],
Coca Cola:[
{name: 'Vika' company: 'Coca Cola', id : 2},
{name: 'Fibi' company: 'Coca Cola', id : 5},
],
"Jonson & Jonson":[
{name: 'Alex' company: 'Jonson & Jonson', id : 3},
]
}
*/
employee.forEach((each)=>{
if(companies.indexOf(each.company) != -1)
interm[`${each.company}`].push(each)
})
//Now our intermediate data is ready
//We need to convert to our desirable format
let finalArray = []
Object.keys(interm).forEach((each)=>{
finalArray.push({each:interm[`${each}`]})
})
console.log(finalArray)

What is smallest way to split object into array of object based on key/value pairs in Javascript?

I've got this object:
var obj = {
family : [{name: 'will', age: 30}, {name: 'husain', age: 12}],
friends : [{name: 'cody', age: 31}, {name: 'jeff', age: 11}],
school : [{name: 'daniel', age: 20}, {name: 'carl', age: 15}]
}
convert it into this
var obj = [
{family : [{name: 'will', age: 30}, {name: 'husain', age: 12}]},
{friends : [{name: 'cody', age: 31}, {name: 'jeff', age: 11}]},
{school : [{name: 'daniel', age: 20}, {name: 'carl', age: 15}]}
];
Write now I am using for..in to build a new array and create object with key as key for new object and so on.
I'm doing this right now
var arr = [];
for (let key in obj) {
arr.push({key: obj[key]})
}
I think Object.keys is your best option:
var obj = {
family : [{name: 'will', age: 30}, {name: 'husain', age: 12}],
friends : [{name: 'cody', age: 31}, {name: 'jeff', age: 11}],
school : [{name: 'daniel', age: 20}, {name: 'carl', age: 15}]
}
var r = Object.keys(obj).map(x => ({[x]: obj[x]}) )
console.log(r)

Javascript merge array values belonging to different keys in object

I have an object like this:
data = {
0: [{name: 'ABC', age: '43'}, {name: 'DEF', age: '20'}],
1: [{name: 'GHI', age: '41'}, {name: 'JKL', age: '25'}],
2: [{name: 'MNO', age: '19'}, {name: 'PQR', age: '24'}]
};
I want to merge the array values of the keys, and make a single array of objects like this:
[ {name: 'ABC', age: '43'}, {name: 'DEF', age: '20'}, {name: 'GHI', age: '41'}, {name: 'JKL', age: '25'}, {name: 'MNO', age: '19'}, {name: 'PQR', age: '24'} ]
I went through the Lodash docs to find something, but cannot come up with the right combination. Does anyone know how to do this in a concise way, with Lodash (preferably), or something else? Thanks in advance!!
Extract the arrays using _.values(), and apply concat to the arrays:
var data = {
0: [{name: 'ABC', age: '43'}, {name: 'DEF', age: '20'}],
1: [{name: 'GHI', age: '41'}, {name: 'JKL', age: '25'}],
2: [{name: 'MNO', age: '19'}, {name: 'PQR', age: '24'}]
};
var result = Array.prototype.concat.apply([], _.values(data));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
You just need to convert the array like object to an array, then flatten it.
data = {
0: [{name: 'ABC', age: '43'}, {name: 'DEF', age: '20'}],
1: [{name: 'GHI', age: '41'}, {name: 'JKL', age: '25'}],
2: [{name: 'MNO', age: '19'}, {name: 'PQR', age: '24'}]
};
console.log(
_.flatten(_.toArray(data))
)
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
Without lodash, just plain old JS:
var data = {
0: [{name: 'ABC', age: '43'}, {name: 'DEF', age: '20'}],
1: [{name: 'GHI', age: '41'}, {name: 'JKL', age: '25'}],
2: [{name: 'MNO', age: '19'}, {name: 'PQR', age: '24'}]
};
var result = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
result = result.concat(data[key]);
}
}
console.log(result);
With the new Object.values() you may do as follows in pure JS ES6;
var data = { 0: [{name: 'ABC', age: '43'}, {name: 'DEF', age: '20'}],
1: [{name: 'GHI', age: '41'}, {name: 'JKL', age: '25'}],
2: [{name: 'MNO', age: '19'}, {name: 'PQR', age: '24'}]
},
newData = [].concat(...Object.values(data));
console.log(newData);
Here is another pure javascript version.
var data = {
0: [{name: 'ABC', age: '43'}, {name: 'DEF', age: '20'}],
1: [{name: 'GHI', age: '41'}, {name: 'JKL', age: '25'}],
2: [{name: 'MNO', age: '19'}, {name: 'PQR', age: '24'}]
};
var newdata = Object.keys(data).reduce(function (a,b) {
return a.concat(data[b]);
}, []);
console.log(newdata);

Categories