Create an array of objects from a nested object - javascript

I've a nested object 'empData'.
I need to iterate over each of the keys in my object and return an array of objects.
Each key inside my object 'empData' is again an object.
Now, I need to return an array of object as:
Expected output:
[{
"team": "AUS",
"name": "John"
}, {
"team": "CAN",
"name": "Steve"
}, {
"team": "IND",
"name": "Robbie"
}, {
"team": "IRE",
"name": "James"
}, {
"team": "USA",
"name": "Austin"
}];
My Code:
function getData() {
const empData = {
"AUS": {
"isRetired": true,
"name": "John"
},
"CAN": {
"name": "Steve"
},
"IND": {
"name": "Robbie"
},
"IRE": {
"name": "James"
},
"USA": {
"name": "Austin"
}
};
Object.keys(empData).map(function(eachKey) {
const obj = {
team: eachKey,
name: eachKey.name
};
console.log(obj);
return obj;
});
}
<button onclick="getData()">Get Data</button>
Could someone please help me with this?

change name: eachKey.name
name: empData[eachKey].name
function getData() {
const empData = {
"AUS": {
"isRetired": true,
"name": "John"
},
"CAN": {
"name": "Steve"
},
"IND": {
"name": "Robbie"
},
"IRE": {
"name": "James"
},
"USA": {
"name": "Austin"
}
};
Object.keys(empData).map(function(eachKey) {
const obj = {
team: eachKey,
name: empData[eachKey].name
};
console.log(obj);
return obj;
});
}

.map the Object.entries instead, so you can extract both the key (to get the team and the value (so you can get the name) at once:
const empData = {
"AUS": {
"isRetired": true,
"name": "John"
},
"CAN": {
"name": "Steve"
},
"IND": {
"name": "Robbie"
},
"IRE": {
"name": "James"
},
"USA": {
"name": "Austin"
}
};
const getData = () => {
const result = Object.entries(empData).map(([team, { name }]) => ({
team,
name
}));
console.log(result);
};
<button onclick="getData()">Get Data</button>

You can use Object.entries to convert the object into an array. Use map to loop thru the array.
Object.entries first element is the key and the second is the value.
const empData = {
"AUS": {
"isRetired": true,
"name": "John"
},
"CAN": {
"name": "Steve"
},
"IND": {
"name": "Robbie"
},
"IRE": {
"name": "James"
},
"USA": {
"name": "Austin"
}
};
var result = Object.entries(empData).map(([team, {name}]) => ({team,name}));
console.log(result);

You can use for..in to iterate iver the object and create a new object with relevant keys and values and push to another array
function getData() {
const empData = {
"AUS": {
"isRetired": true,
"name": "John"
},
"CAN": {
"name": "Steve"
},
"IND": {
"name": "Robbie"
},
"IRE": {
"name": "James"
},
"USA": {
"name": "Austin"
}
};
let newData = [];
for (let keys in empData) {
newData.push({
team: keys,
name: empData[keys].name
})
}
console.log(newData)
}
getData()

Related

Creating an object which contains unique item from a nested array

I have an array of objects called employees. I need a solution that will return me a list of groups and respective employees present in the group along with the group properties.
The example is below, I have used an object but the result can also be an array that has a property called groupName within an object. [{groupName:"developer", employees:[],...}..] As long as the response returns a list of groups with their corresponding employees.
Below is the solution I did but I need a solution with a better time complexity that is O(n).
const employees = [
{ "name": "John Doe",
"id": "1",
"groups": [
{ "id": "developerId", "name": "developer", "color": "#fff" },
{ "id": "engineerId", "name": "engineer", "color": "#fff" }
],
"groupId":["developerId", "engineerId"]
},
{ "name": "Jane Doe",
"id": "2",
"groups": [
{ "id": "developerId", "name": "developer", "color": "#fff" },
{ "id": "testerId", "name": "tester", "color": "#fff" }
],
"groupId":["developerId", "testerId"]
}
]
//Solution O(m*n)
let groups = {};
employees.forEach((item) => {
item.groups.forEach((group) => {
if (!groups[group.name]) {
groups[group.name] = {
employees: [item.id],
...group,
};
} else {
groups[group.name].employees = [...groups[group.name].employees, item.id];
}
});
});
//result
{
"developer":{
"id":"developerId",
"employee":[
"1",
"2"
],
"color":"#fff"
},
"engineer":{
"id":"employeeId",
"employee":[
"1",
],
"color":"#fff"
},
"tester":{
"id":"testerId",
"employee":[
"2",
],
"color":"#fff"
}
}
Using Array#reduce and Array#forEach:
const employees = [
{
"name": "John Doe",
"id": "1",
"groups": [
{ "id": "developerId", "name": "developer", "color": "#fff" },
{ "id": "engineerId", "name": "engineer", "color": "#fff" }
],
"groupId": ["developerId", "engineerId"]
},
{
"name": "Jane Doe",
"id": "2",
"groups": [
{ "id": "developerId", "name": "developer", "color": "#fff" },
{ "id": "testerId", "name": "tester", "color": "#fff" }
],
"groupId": ["developerId", "testerId"]
}
];
const groups = employees.reduce((acc, { id: employeeId, groups = [] }) => {
groups.forEach(({ id, name, color }) => {
acc[name] = {
id, color, employee: [...(acc[name]?.employee ?? []), employeeId]
};
});
return acc;
}, {});
console.log(groups);
If you like to add some speed, you could use the old fashioned for statement for iterating, especially of having only a single result object.
This approach does not create an object again and again and uses the already existing objects.
const
employees = [{ name: "John Doe", id: "1", groups: [{ id: "developerId", name: "developer", color: "#fff" }, { id: "engineerId", name: "engineer", color: "#fff" }], groupId: ["developerId", "engineerId"] }, { name: "Jane Doe", id: "2", groups: [{ id: "developerId", name: "developer", color: "#fff" }, { id: "testerId", name: "tester", color: "#fff" }], groupId: ["developerId", "testerId"] }],
result = {};
for (const { id: employeeId, groups } of employees) {
for (const { id, name, color } of groups) {
result[name] ??= { id, color, employee: [] };
result[name].employee.push(employeeId);
}
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to filter from an object by iterating over it in js

I am trying to get the value of "type" from the object by iterating over it. The object looks like this.
{
"team": {
"table": [
{
"cityCode": 123,
"list": {
"players": [
{
"name": "peter",
"school": "x",
"awards": {
"type": "gold"
},
"year": 2019
}
]
}
},
{
"cityCode": 456,
"list": {
"players": [
{
"name": "Dave",
"school": "y",
"awards": {
"type": "silver"
},
"year": 2018
}
]
}
}
]
}
}
I am able to get the type values using this:
const table = team.table;
for (let i = 0; i < table.length; i++) {
const values = {
type: table[i].list.players
.filter((a) => a.awards != null)
.map((a) => a.awards.type)
.join(" "),
};
}
However, I want to use another filter on the "list" to filter non null lists. So how can I achieve that.
You want to check Check if 'list' key exists inside a team.table JSON object
you can check by
if(table[i].hasOwnProperty('list')){
}
code is
const table = team.table;
for (let i = 0; i < table.length; i++) {
if(table[i].hasOwnProperty('list')){
const values = {
type: table[i].list.players
.filter((a) => a.awards != null)
.map((a) => a.awards.type)
.join(" "),
};
}
}
1) You can get all type using flatMap and map as:
obj.team.table.flatMap((o) => o.list.players.map((o) => o.awards.type))
const obj = {
team: {
table: [
{
cityCode: 123,
list: {
players: [
{
name: "peter",
school: "x",
awards: {
type: "gold",
},
year: 2019,
},
],
},
},
{
cityCode: 456,
list: {
players: [
{
name: "Dave",
school: "y",
awards: {
type: "silver",
},
year: 2018,
},
],
},
},
],
},
};
const types = obj.team.table.flatMap((o) => o.list.players.map((o) => o.awards.type));
console.log(types);
2) Using forEach and destructuring as:
const obj = {
team: {
table: [
{
cityCode: 123,
list: {
players: [
{
name: "peter",
school: "x",
awards: {
type: "gold",
},
year: 2019,
},
],
},
},
{
cityCode: 456,
list: {
players: [
{
name: "Dave",
school: "y",
awards: {
type: "silver",
},
year: 2018,
},
],
},
},
],
},
};
const table = obj.team.table;
const types = [];
for (let i = 0; i < table.length; i++) {
const { list: { players } } = table[i]
players.forEach(({ awards: { type }}) => types.push(type))
}
console.log(types);
It will be cleaner to use forEach.
You will need 2 forEach due to your data structure.
But below code will:
check if awards is null
check if awards.type is null
const data = {
"team": {
"table": [
{
"cityCode": 123,
"list": {
"players": [
{
"name": "peter",
"school": "x",
"awards": {
"type": "gold"
},
"year": 2019
}
]
}
},
{
"cityCode": 456,
"list": {
"players": [
{
"name": "Dave",
"school": "y",
"awards": {
"type": "silver"
},
"year": 2018
},
{
"name": "Dave",
"school": "y",
"awards": {
"type": "gold"
},
"year": 2016
}
]
}
},
{
"cityCode": 444,
"list": {
"players": [
{
"name": "James",
"school": "y",
"awards": {
"type": null
},
"year": 2016
}
]
}
},
{
"cityCode": 555,
"list": {
"players": [
{
"name": "Name 101",
"school": "y",
"awards": {
"type": "platinum"
},
"year": 2016
},
{
"name": "Name 102",
"school": "y",
"awards": {
"type": null
},
"year": 2016
},
{
"name": "Name 103",
"school": "y",
"awards": null,
"year": 2016
},
]
}
}
]
}
}
// Expanded your data with more items
const data1 = data.team.table;
let types = []
data1.forEach((item, index) => {
item.list.players.forEach((player) => {
const awards = player.awards;
if (awards !== null && awards.type !== null) {
types = [...types, awards.type];
}
})
})
// Get the list of types
console.log(types);
// Get unique list of types
let unique_types = [...new Set(types)]
console.log(unique_types);

push elements of each object inside each object inside another array

I have two arrays, one is my original one called data which consists of :
const datas = [
{
name: 'core Test',
item: [
{
name: 'test/core/core.js',
item: "item1"
}
]
},
{
name: 'users Test',
item: [
{
name: 'test/users/user.js',
item: "item2"
}
]
}
]
And i have another array called replace, which i'm trying to push each of its elements inside my original one, inside the
const replace = [
{
type: "test1",
number: "1",
},
{
type: "test2",
number: "2",
}
]
Here is my code :
const transformedData = datas.map(data => {
data.item = data.item.map(x => ({
name: x.name,
type: replace.map(y=>{return y;})
}))
return data
})
The output i get :
[
{
"name": "core Test",
"item": [
{
"name": "test/core/core.js",
"type": [
{ "type": "test1", "number": "1" },
{ "type": "test2", "number": "2" }
]
}
]
},
{
"name": "users Test",
"item": [
{
"name": "test/users/user.js",
"type": [
{ "type": "test1", "number": "1" },
{ "type": "test2", "number": "2" }
]
}
]
}
]
The output i want :
[
{
"name": "core Test",
"item": [
{
"name": "test/core/core.js",
"type": { "type": "test1", "number": "1" }
}
]
},
{
"name": "users Test",
"item": [
{
"name": "test/users/user.js",
"type": { "type": "test2", "number": "2" }
}
]
}
]
This is because you're mapping all the way through the replace array every single time for each time you're inside of a value inside of datas. Instead you want to keep track of the index with your original map so then you only have one instance each time.
Try something like:
const transformedData = datas.map((data, index) => {
data.item = data.item.map(x => ({
name: x.name,
type: replace[index]
}))
return data;
});

Create new javascript object from 2 JSON objects grouped by id

I have below dynamic nested JSON object arrays and I wanted to get the desired output with JavaScript grouped by id from both.
First Array:
[
{
"id": "11",
"name": "emp1",
"location": [
{ "name": "abc", "id": "lc1" }
]
},
{
"id": "11",
"name": "emp2",
"location": [
{ "name": "abc", "id": "lc1" },
]
},
{
"id": "22",
"name": "emp3",
"location": [
{ "name": "xyz", "id": "lc2" }
]
}
]
Second array like below.
[
{
"name": "sub1",
"id": "11"
...
},
{
"name": "sub1.1",
"id": "11"
...
},
{
"name": "sub2",
"id": "22"
...
}
]
Desired Output:
[
{
"id": "11",
"first": [{"name": "emp1"},
{"name": "emp2"}],
"second": [{"name": "sub1"},{"name": "sub1.1"}],
"location": [{"name": "abc"}]
},
{
"id": "22",
"first": [{"name": "emp3"}],
"second": [{"name": "sub2"}],
"location": [{"name": "xyz"}]
}
]
How to get the desired output like above using javascript/angularjs?
I would do it using the amazing Array#reduce function.
Note that I have named your first array as a1, second as a2 and result as res.
a1.reduce(function(arr, obj) {
var existing = arr.filter(function(res) {
return res.id === obj.id
})[0]
if (existing) {
existing.first.push({
name: obj.name
})
} else {
var second = a2.filter(function(res) {
return res.id === obj.id
})
var secondObj = second.length ? second.map(function(sec) {
return {
name: sec.name
};
}) : []
arr.push({
id: obj.id,
first: [{
name: obj.name
}],
second: secondObj,
location: obj.location
})
}
return arr;
}, [])
Here's the working snippet. Take a look!
var a1 = [{
"id": "11",
"name": "emp1",
"location": [{
"name": "abc",
"id": "lc1"
}]
},
{
"id": "11",
"name": "emp2",
"location": [{
"name": "abc",
"id": "lc1"
}]
},
{
"id": "22",
"name": "emp3",
"location": [{
"name": "xyz",
"id": "lc2"
}]
}
]
var a2 = [{
"name": "sub1",
"id": "11"
}, {
"name": "sub1.1",
"id": "11"
},
{
"name": "sub2",
"id": "22"
}
]
var res = a1.reduce(function(arr, obj) {
var existing = arr.filter(function(res) {
return res.id === obj.id
})[0]
if (existing) {
existing.first.push({
name: obj.name
})
} else {
var second = a2.filter(function(res) {
return res.id === obj.id
})
var secondObj = second.length ? second.map(function(sec) {
return {
name: sec.name
};
}) : []
arr.push({
id: obj.id,
first: [{
name: obj.name
}],
second: secondObj,
location: obj.location
})
}
return arr;
}, [])
console.log(res)
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
var red1 = [{
"id": "11",
"name": "emp1",
"location": [{
"name": "abc",
"id": "lc1"
}]
},
{
"id": "11",
"name": "emp2",
"location": [{
"name": "abc",
"id": "lc1"
}]
},
{
"id": "22",
"name": "emp3",
"location": [{
"name": "xyz",
"id": "lc2"
}]
}
]
var b = [{
"name": "sub1",
"id": "11"
},
{
"name": "sub2",
"id": "22"
}
]
var identication = {}
var result = []
red1.forEach(function(val) {
if (val['id'] in identication) {
var t = {}
t['name'] = val['name']
result[identication[val['id']]]['first'].push(t)
} else {
var t = {}
t['name'] = val['name']
val['first'] = []
val['first'].push(t)
delete val['name']
var identity = result.push(val)
identication[val['id']] = identity - 1;
}
})
b.forEach(function(d) {
if (d['id'] in identication) {
var t = {
'name': d['name']
}
if (!('second' in result[identication[d['id']]])) {
result[identication[d['id']]]['second'] = []
}
result[identication[d['id']]]['second'].push(t)
} else {
var t = {}
for (key in d) {
if (key == 'name')
continue
t[key] = d[key]
}
t['second'] = [{
'name': d['name']
}]
var identity = result.push(t)
identication[d['id']] = identity - 1;
}
})
console.log(result)

Javascript get name from data by id function

I need to create a function the would return the name of the car when given the id.
I have this data:
{
"cars": [
{
"id": "661",
"name": "ford"
},
{
"id": "657",
"name": "fiat",
},
{
"id": "654",
"name": "volvo",
},
{
"id": "653",
"name": "porche",
},
{
"id": "650",
"name": "mazda",
}
]
}
So I've done this:
function getCarNameFromId(id) {
theData = {
"cars": [
{
"id": "661",
"name": "ford"
},
{
"id": "657",
"name": "fiat",
},
{
"id": "654",
"name": "volvo",
},
{
"id": "653",
"name": "porche",
},
{
"id": "650",
"name": "mazda",
}
]
};
console.log(theData.name);
}
then call it:
function getCarNameFromId('650');
How do I finish this code so I can get the code to return me the name of the id specified?
JS solution
var findCar = function(id) {
var theData = {
"cars": [{
"id": "661",
"name": "ford"
},
{
"id": "657",
"name": "fiat",
},
{
"id": "654",
"name": "volvo",
},
{
"id": "653",
"name": "porche",
},
{
"id": "650",
"name": "mazda",
}
]
};
for (var i = 0; i < theData.cars.length; i++) {
var car = theData.cars[i];
if (car.id === id)
return car.name;
}
}
console.log(findCar("654"));
If you are using any mordenr browser you can use find method to find object from array
function getCarNameFromId(id) {
......
..........
.....
var obj = theData.cars.find( function(el) {
return el.id == id
})
if(obj){
return obj.name
} else {
return ''; // or just without any value.
}
}
if still want to support old browsers i would recommand to use lodash.js or underscore.js
cars.find(car => car.id === id).name
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Categories

Resources