Loop through nested json array to create new array - javascript

I am working on a lambda function that GETs data from one API and POSTs it to another. The data is a list of contacts with properties, e.g. first name, last name, email, etc.
The JSON output contains too many properties that I don't need. See below code example (actual code contains many more properties and nested arrays/objects).
{
"contacts": [
{
"addedAt": 1532803458796,
"vid": 101
}
],
"merge-audits": [],
"properties": {
"first-name": {
"value":"hello"
},
"last-name": {
"value":"there"
},
"email": {
"value":"hello#there.com"
}
...
...
}
How can I loop through each JSON object to create a new, simpler JSON array like the following:
[
{
"email": "example#example.com",
"first_name": "",
"last_name": "User"
},
{
"email": "example2#example.com",
"first_name": "Example",
"last_name": "User"
}
]
Thanks in advance for your help.

try
json.map( x => ({
email: x.properties.email.value,
first_name: x.properties['first-name'].value,
last_name: x.properties['last-name'].value,
}));
let json = [
{
"contacts": [{
"addedAt": 1532803458796,
"vid": 101
}],
"merge-audits": [],
"properties": {
"first-name": {
"value": "hello"
},
"last-name": {
"value": "there",
},
"email": {
"value": "hello#there.com"
}
}
},
{
"contacts": [{
"addedAt": 1532803458796,
"vid": 101
}],
"merge-audits": [],
"properties": {
"first-name": {
"value": "Tom"
},
"last-name": {
"value": "Smith",
},
"email": {
"value": "tom#smith.com"
}
}
}
]
let r = json.map(x => ({
email: x.properties.email.value,
first_name: x.properties['first-name'].value,
last_name: x.properties['last-name'].value,
}));
console.log(r);

You could use a destructuring assignment for the object and short hand properties for the mapping.
var data = [{ contacts: [{ addedAt: 1532803458796, vid: 101 }], "merge-audits": [], properties: { "first-name": { value: "hello" }, "last-name": { value: "there" }, email: { value: "hello#there.com" } } }],
result = data.map(({ properties: {
'first-name': { value: first_name },
'last-name': { value: last_name },
email: { value: email }
} }) => ({ first_name, last_name, email }));
console.log(result);

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 access nested objects within an array in the following example using Javascript "map" method?

How do I access the following keys within this array of objects using the 'map' method? I want to access:
'id' inside 'moreInfo'
'fore' inside 'distances'
I get undefined for the following fields when I use
a.map((d) => console.log(d.moreInfo.id));
. I want to use the 'map' method itself so that I can render this content in my React application.
let a = [
{
"Id": "huih23432",
"name": "Kevin",
"dob": "26/06/1995",
"nid": "34535353543",
"images": {
"id": "https://picsum.photos/200",
"nid": "https://picsum.photos/200"
}
},
{
"moreInfo": [
{
"id": "243423423423",
"dob": "16/07/1990",
"name": "JD",
"images": {
"id": "https://picsum.photos/200",
"nid": "https://picsum.photos/200"
},
"distances": {
"fore": "0.91",
"towards": "0.5"
}
}
]
}
];
Try this.
let a = [
{
"Id": "huih23432",
"name": "Kevin",
"dob": "26/06/1995",
"nid": "34535353543",
"images": {
"id": "https://picsum.photos/200",
"nid": "https://picsum.photos/200"
}
},
{
"moreInfo": [
{
"id": "243423423423",
"dob": "16/07/1990",
"name": "JD",
"images": {
"id": "https://picsum.photos/200",
"nid": "https://picsum.photos/200"
},
"distances": {
"fore": "0.91",
"towards": "0.5"
}
}
]
}
];
a.filter(d => d.moreInfo)
.map((d)=>{
const moreInfoObj = d.moreInfo.find(y => y.id);
console.log("'id' inside 'moreInfo': " + moreInfoObj.id);
console.log("'fore' inside 'distances': " + moreInfoObj.distances.fore);
});
Actually you data array of objects and each object has different props. You can use destructuring with default values.
let a = [
{
Id: "huih23432",
name: "Kevin",
dob: "26/06/1995",
nid: "34535353543",
images: {
id: "https://picsum.photos/200",
nid: "https://picsum.photos/200",
},
},
{
moreInfo: [
{
id: "243423423423",
dob: "16/07/1990",
name: "JD",
images: {
id: "https://picsum.photos/200",
nid: "https://picsum.photos/200",
},
distances: {
fore: "0.91",
towards: "0.5",
},
},
],
},
];
a.map(({ moreInfo: [{ id, distances: { fore } = {} }] = [{}] }) =>
console.log({ id, fore })
);

Create an array of objects from a nested object

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()

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;
});

How to normalize this with normalizr?

Consider the User object passed back:
{
"id": "123",
"username": "TestUser",
"group":
{
"id": "324",
"name": "My Group"
}
}
I want to run: normalize(user);
And get something like this back. Is it possible? Or is it correct? I am trying to extract the group from the user, so I can place it in its own entities slot.
{
result: "123",
entities: {
"users": {
"123": {
id: "123",
group: "1",
username: "TestUser
}
},
"groups": {
"1": { "id": "324", "name": "My Group" },
}
}
}
I'm not quite sure what my schemas should look like to achieve this result.
Figured it out. Didn't realize it was so straightforward.
export const group = new schema.Entity('groups', {}, {
idAttribute: 'id'
});
export const user = new schema.Entity(
'users',
{
group: group
},
{
idAttribute: 'id'
}
);

Categories

Resources