I have a javascript object which has the nested array called interaction, now what I wanted to do is a loop from each object of the main array and fetch the values from the interaction array, I'm a kind of a newbie with iteration and looping. here below is the object
var data = [{
'id':'1',
'boothid':[{'id':'1','name':'yyy'}],
'interaction':[{
'userid':'1',
'username':'user1',
},{
'userid':'2',
'username':'user2',
}]
},
{
'id':'2',
'boothid':[{'id':'2','name':'xxx'}],
'interaction':[{
'userid':'4',
'username':'user4',
},
{
'userid':'5',
'username':'user5',
},
{
'userid':'6',
'username':'user6',
}],
'resource':'2',
},
{
'id':'3',
'boothid':[{'id':'2','name':'zzz'}],
'interaction':[{
'userid':'4',
'username':'user4',
}],
'resource':'3',
}]
console.log(data);
expected output
yyy
{
"userid": "1",
"username": "user1"
}
{
"userid": "2",
"username": "user2"
}
xxx
{
"userid": "4",
"username": "user4"
}
{
"userid": "5",
"username": "user5"
}
{
"userid": "6",
"username": "user6"
}
zzz
{
"userid": "4",
"username": "user4"
}
here what I'm trying to achieve is, I want to loop from the data object and show that in the frontend, so basically the output will be in 3 tables with respected booth names ex: table1= xxx, table2=yyy, table3=zzz, and the users in a particular booth will be displayed at td of theirs table.
You can use a .map. I made some assumptions:
At the time of writing the expected output has non-unique properties in single objects in the "itarations" array. Maybe you intended to have that object split into separate objects, each with its own "username" property.
"itarations" is a non-existent word. Maybe you meant "interactions".
In the example, the boothid array has always one entry. I'll assume this is always the case.
The code:
let data = [{id:'1',boothid:[{id:'1',name:'yyy'}],interaction:[{userid:'1',username:'user1',},{userid:'2',username:'user2',}]},{id:'2',boothid:[{id:'2',name:'xxx'}],interaction:[{userid:'4',username:'user4',},{userid:'5',username:'user5',},{userid:'6',username:'user6',}],resource:'2',},{id:'3',boothid:[{id:'2',name:'zzz'}],interaction:[{userid:'4',username:'user4',}],resource:'3',}];
let result = data.map(o => ({
boothname: o.boothid[0].name,
interactions: o.interaction.map(({username}) => ({ username }))
}));
console.log(result);
I suggest you to use the map function.
var data = [
{
'id':'1',
'boothid':[{'id':'1','name':'yyy'}],
'interaction':[
{'userid':'1', 'username':'user1'},
{'userid':'2', 'username':'user2'}
]
},
{
'id':'2',
'boothid':[{'id':'2','name':'xxx'}],
'interaction':[
{'userid':'4', 'username':'user4'},
{'userid':'5', 'username':'user5'},
{'userid':'6', 'username':'user6'}
]
}
];
var result = data.map(({boothid, interaction}) => ({
boothname: boothid[0].name,
interaction
}));
console.log(result);
You can try this.
var data = [
{
'id':'1',
'boothid':[{'id':'1','name':'yyy'}],
'interaction':[{
'userid':'1',
'username':'user1',
},{
'userid':'2',
'username':'user2',
}]
},
{
'id':'2',
'boothid':[{'id':'2','name':'xxx'}],
'interaction':[{
'userid':'4',
'username':'user4',
},
{
'userid':'5',
'username':'user5',
},
{
'userid':'6',
'username':'user6',
}],
'resource':'2',
},
{
'id':'3',
'boothid':[{'id':'2','name':'zzz'}],
'interaction':[{
'userid':'4',
'username':'user4',
}],
'resource':'3',
}];
var result = data.map(({boothid, interaction}) => ({
boothname: boothid[0].name,
interaction: interaction.map(({username}) => username)
}));
console.log(result);
friends thank you for your response and ideas, as andy mentioned link the above comment helped me to get the required answer. here below is my answer
var data = [{
'id':'1',
'boothid':[{'id':'1','name':'yyy'}],
'interaction':[{
'userid':'1',
'username':'user1',
},{
'userid':'2',
'username':'user2',
}]
},
{
'id':'2',
'boothid':[{'id':'2','name':'xxx'}],
'interaction':[{
'userid':'4',
'username':'user4',
},
{
'userid':'5',
'username':'user5',
},
{
'userid':'6',
'username':'user6',
}],
'resource':'2',
},
{
'id':'3',
'boothid':[{'id':'2','name':'zzz'}],
'interaction':[{
'userid':'4',
'username':'user4',
}],
'resource':'3',
}]
for (let i of data){
console.log(i.boothid[0].name);
for(let j of i.interaction ){
console.log(j);
}
}
let interactions = [];
data.map(obj => {
interactions.push({
boothname: obj.boothid[0].name,
interactions: obj.interaction,
})
})
You can loop over "data" array with map it will give you each element on iteration where you can pick boothname from "obj.boothid" and interactions from "obj.interaction".
Related
I know that this is close to a duplicate but I can't get the code to work. I have an object that I need to filter and I'm currently trying to emulate the accepted as an answer the code at Javascript filtering nested arrays
My data object is:
[{
"project_num": "5R01DA012513-23",
"principal_investigators": [{
"profile_id": 2076451,
"full_name": "PK",
"title": ""
}]
},
{
"project_num": "5R01DK118529-03",
"principal_investigators": [{
"profile_id": 8590844,
"full_name": "HW",
"title": "PROFESSOR, SCIENTIFIC DIRECTOR"
}]
},
{
"project_num": "3R01AA025365-05S1",
"principal_investigators": [{
"profile_id": 8730036,
"full_name": "JJ",
"title": "ASSOCIATE PROFESSOR OF PSYCHIATRY"
}]
},
{
"project_num": "1R01HL163963-01",
"principal_investigators": [{
"profile_id": 2084037,
"full_name": "KH",
"title": "ASSOCIATE PROFESSOR"
},
{
"profile_id": 11309656,
"full_name": "AM",
"title": "RESEARCH ASSISTANT PROFESSOR"
}
]
},
{
"project_num": "5R25HL092611-15",
"principal_investigators": [{
"profile_id": 1886512,
"full_name": "CW",
"title": "P"
}]
}
]
and my JavaScript code is:
let payLoad = 1886512
const result = this.reporterData.map(t => {
const principal_investigators = t.principal_investigators.filter(d =>
d.profile_id === payLoad);
return { ...t,
principal_investigators
};
})
I need to pass in a profile_id as a payload and return the objects that will fill a data table.
The data can be 1000's of items and the principla_investigators can be multiple entries. When I use the code that I have it return all of the objects. Can someone point out my error? Thanks
You can try doing like this:
const result = this.reporterData.filter((t) => {
const principal_investigators = t.principal_investigators.filter((d) => d.profile_id === payLoad)
return (principal_investigators.length > 0)
})
I understand that you want an array with all the investigators matching that ID, right?
Try this:
const result = this.reporterData.reduce((previous, current) => {
if (current.principal_investigators) {
current.principal_investigators.forEach(pi => {
if (pi.profile_id === payLoad) {
previous.push(current)
}
});
}
return previous
}, [])
You can also do for loops with the same result:
const result = [];
for (project of this.reporterData) {
if (project.principal_investigators) {
for (pi of project.principal_investigators) {
if (pi.profile_id == payLoad) {
result.push(pi);
}
}
}
}
I try to mapping nested JSON in React JS.
My JSON data like this,
"beautifuldata": [
{ "id":"1", "name":"a"},
{ "id":"2", "name":"b"},
{ "id":"3", "name":"c"},
{ "id":"4", "name":"d"},
{ "id":"5", "name":"e"},
{ "id":"6", "name":"f"},
{ "id":"7", "name":"g"}]
this data came from an API. And I can write my data to the console. But everything went wrong when I try to access the inner side. For example, I want to get id from my JSON data,
I try this
[beautifuldata].map(x => console.log(x));
this code line gave all data,
[beautifuldata].map(x => console.log(x.id));
this code line gave me undefined. I want to access all data inside my JSON. What am I missing?
You are returning the whatever console.log(x.id) returns which is undefined;
You need to return the x.id
let obj = {
beautifuldata: [
{ id: "1", name: "a" },
{ id: "2", name: "b" },
{ id: "3", name: "c" },
{ id: "4", name: "d" },
{ id: "5", name: "e" },
{ id: "6", name: "f" },
{ id: "7", name: "g" },
],
};
const result = obj.beautifuldata.map((x) => x.id);
console.log(result);
remove [ ] from this line
[beautifuldata].map(x => console.log(x.id));
To read
beautifuldata.map(x => console.log(x.id));
EDIT
If you want to access data outside the map function,
beautifuldata.map(x => {
/* Work with x properties here*/
console.log(x.id)
return x
}
// thanks to #mhodges
I suggest a solution like below might be an appropriate approach.
var rst = {
"beautifuldata": [
{ "id":"1", "name":"a"},
{ "id":"2", "name":"b"},
{ "id":"3", "name":"c"},
{ "id":"4", "name":"d"},
{ "id":"5", "name":"e"},
{ "id":"6", "name":"f"},
{ "id":"7", "name":"g"}]
}
rst.beautifuldata.map(i => console.log(i.id));
/* -- or --- */
rst.beautifuldata.forEach(i => console.log(i.id));
Hope that helps or gives you a hint.
array data=[
{
"id":1,
"name":"john",
"income":22000,
"expenses":15000
},
{
"id":2,
"name":"kiran",
"income":27000,
"expenses":13000
},
{
"id":1,
"name":"john",
"income":35000,
"expenses":24000
}
]
i want to make a new array set in following format which is in a key value pair. ie result set.
can you please explain the best method. ? how to achive using foreach.?
tried using foreach method by looping each element. but cant get the desired output format
var result= [ {
"name": "john",
"series": [
{
"name": "income",
"value": 22000
},
{
"name": "expenses",
"value": 15000
},
]
},
{
"name": "kiran",
"series": [
{
"name": "income",
"value": 27000
},
{
"name": "expenses",
"value": 13000
},
]
}]
// Your array
const result = [
{
name: "john",
series: [
{
name: "income",
value: 22000,
},
{
name: "expenses",
value: 15000,
},
],
},
{
name: "kiran",
series: [
{
name: "income",
value: 27000,
},
{
name: "expenses",
value: 13000,
},
],
},
];
// What is .map function?
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
// Output
// map return a new function.
// it's a loop method but more equipped
result.map((item, index) => {
const seriesKeyValues = {};
// forEach is too, it's a loop method.
// but not have a return value,
// just loops and give you item on each loop
item.series.forEach(serie => {
//seriesKeyValues is a object.
// different between seriesKeyValues.serie.name
// it's a bracket notation
// look this documentation
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names
seriesKeyValues[serie.name] = serie.value;
});
// return new Object
// ... is 'spread syntax' basically combine objects
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#spread_properties
// spread syntax is a new way.
// old way is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
return {
id: index,
name: item.name,
...seriesKeyValues,
};
});
I hope it will help :). if you don't understand any lines of code, i can explain
My target is if the id from digital_assets and products matches then get the value of URL fro digital_assets and ProductName from products object. I'm able to traverse through the object and get the values of digital_assets and products but need some help to compare these two objects based on IDs to get the value of URL and ProductName. Below is what I've done so far.
var data = [{
"digital_assets": [{
"id": "AA001",
"url": "https://via.placeholder.com/150"
},{
"id": "AA002",
"url": "https://via.placeholder.com/150"
}]
}, {
"products": [{
"id": ["BB001", "AA001"],
"ProductName": "PROD 485"
},{
"id": ["BB002", "AA002"],
"ProductName": "PROD 555"
}]
}
];
$.each(data, function () {
var data = this;
//console.log(data);
$.each(data.digital_assets, function () {
var dAssets = this,
id = dAssets['id'];
// console.log(id);
});
$.each(data.products, function () {
var proData = this,
prod_id = proData['id'];
// console.log(prod_id);
$.each(prod_id, function () {
var arr_id = this;
console.log(arr_id);
});
});
});
Do I need to create new arrays and push the values into the new arrays? Then concat() these array to one. ? Bit lost any help will be appreciated.
Here is one way you can do this via Array.reduce, Array.includes, Object.entries and Array.forEach:
var data = [{ "digital_assets": [{ "id": "AA001", "url": "https://via.placeholder.com/150" }, { "id": "AA002", "url": "https://via.placeholder.com/150" } ] }, { "products": [{ "id": ["BB001", "AA001"], "ProductName": "PROD 485" }, { "id": ["BB002", "AA002"], "ProductName": "PROD 555" } ] } ]
const result = data.reduce((r,c) => {
Object.entries(c).forEach(([k,v]) =>
k == 'digital_assets'
? v.forEach(({id, url}) => r[id] = ({ id, url }))
: v.forEach(x => Object.keys(r).forEach(k => x.id.includes(k)
? r[k].ProductName = x.ProductName
: null))
)
return r
}, {})
console.log(Object.values(result))
You can use Array.prototype.find, Array.prototype.includes and Array.prototype.map to achieve this very gracefully.
let data = [
{
"digital_assets": [
{
"id": "AA001",
"url": "https://via.placeholder.com/150"
},
{
"id": "AA002",
"url": "https://via.placeholder.com/150"
}
]
},
{
"products": [
{
"id": ["BB001", "AA001"],
"ProductName": "PROD 485"
},
{
"id": ["BB002","AA002"],
"ProductName": "PROD 555"
}
]
}
];
// Find the 'digital_assets' array
let assets = data.find(d => d['digital_assets'])['digital_assets'];
// Find the 'products' array
let products = data.find(d => d['products'])['products'];
// Return an array of composed asset objects
let details = assets.map(a => {
return {
id : a.id,
url : a.url
name : products.find(p => p.id.includes(a.id)).ProductName
};
});
console.log(details);
changed answer to fit your needs:
var data = [
{
"digital_assets": [
{
"id": "AA001",
"url": "https://via.placeholder.com/150"
},
{
"id": "AA002",
"url": "https://via.placeholder.com/150"
}
]
},
{
"products": [
{
"id": ["BB001", "AA001"],
"ProductName": "PROD 485"
},
{
"id": ["BB002","AA002"],
"ProductName": "PROD 555"
}
]
}
]
let matchingIds = [];
let data_assetsObject = data.find(element => {
return Object.keys(element).includes("digital_assets")
})
let productsObject = data.find(element => {
return Object.keys(element).includes("products")
})
data_assetsObject["digital_assets"].forEach(da => {
productsObject["products"].forEach(product => {
if (product.id.includes(da.id)){
matchingIds.push({
url: da.url,
productName: product.ProductName
})
}
})
})
console.log(matchingIds);
working fiddle: https://jsfiddle.net/z2ak1fvs/3/
Hope that helped. If you dont want to use a new array, you could also store the respective data within the element you are looping through.
Edit:
I think i know why i got downvoted. My example works by making data an object, not an array. changed the snippet to show this more clearly.
Why is data an array anyway? Is there any reason for this or can you just transform it to an object?
Edit nr2:
changed the code to meet the expectations, as i understood them according to your comments. it now uses your data structure and no matter whats in data, you can now search for the objects containing the digital_assets / products property.
cheers
https://jsfiddle.net/2b1zutvx/
using map.
var myobj = data[0].digital_assets.map(function(x) {
return {
id: x.id,
url: x.url,
ProductName: data[1].products.filter(f => f.id.indexOf(x.id) > -1).map(m => m.ProductName)
};
});
Given that I have a JSON structure like this:
{
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever"
}]
}]
}]
}
And I need to map from thirdData value === "whatever"
So I am doing
const result = firstData.map(first => {
return first.secondData.map(second => {
return second.thirdData.map(third => {
return third.value === 'whatever';
});
});
});
And this works somewhat fine, but the result is a another deeply nested array (like [ [ [ {results..} ] ] ]). I know I can flatten this to a single array by other means, but I feel like I am miss using .map(). How can I modify this result to a single array that contains the values of thirdData where the value is what ever I want?
The desired result for this would be a single array of thirdData objects:
[{ value: 'whatever'}, ... {n}]
You can use Array#reduce for reducing into a single value(in this case single array) and Array#forEach for iterating over the nested array.
const data = {
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever"
}]
}]
}]
}
const result = data.firstData.reduce((arr, first) => {
// iterate over the second level array
first.secondData.forEach(second => {
// iterate over the third level array
second.thirdData.forEach(third => {
// push the value into the result array,
// change here, in case you want the value
//arr.push(third.value === 'whatever');
// in case you need the object then do it like
if(third.value === 'whatever') arr.push(third);
});
});
// return the array reference for the next iteration
return arr;
// set the initial value as an array for the result
}, []);
console.log(result);
If you want a flat result, this isn't a use case for map. The simple solution is just to use an array you close over and push to:
const result = [];
firstData.forEach(first => {
return first.secondData.forEach(second => {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
});
});
Live Example with a slight extension to your minimal provided data:
const data = {
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever",
"label": "third #1.1"
},
{
"value": "whatever",
"label": "third #1.2"
},
{
"value": "unrelated",
"label": "unrelated"
}
]
}]
},
{
"secondData": [{
"thirdData": [{
"value": "another unrelated"
},
{
"value": "whatever",
"label": "third #2"
}
]
}]
}
]
};
const result = [];
data.firstData.forEach(first => {
return first.secondData.forEach(second => {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
});
});
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
Note the filter on the thirdData and using spread notation to push that data into result.
That assumes you want the entry from thirdData that has .value === 'whatever' rather than a true/false. If you want the true/false instead, change that filter to map.
Or the for-of equivalent:
const result = [];
for (const first of firstData) {
for (const second of first.secondData) {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
}
}
Live Example with a slight extension to your minimal provided data:
const data = {
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever",
"label": "third #1.1"
},
{
"value": "whatever",
"label": "third #1.2"
},
{
"value": "unrelated",
"label": "unrelated"
}
]
}]
},
{
"secondData": [{
"thirdData": [{
"value": "another unrelated"
},
{
"value": "whatever",
"label": "third #2"
}
]
}]
}
]
};
const result = [];
for (const first of data.firstData) {
for (const second of first.secondData) {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
}
}
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
(Same note about filter/map.)
As with all array operations, you can shoehorn this into reduce, and I guarantee you you'll get answers primarily using reduce, but there's no good reason to use reduce here.
const result = firstData.reduce((result, first) => {
return first.secondData.reduce((result, second) => {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
return result;
}, result);
}, []);
Again, though, there's no good reason for that. It's just more complicated.
Live Example with a slight extension to your minimal provided data:
const data = {
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever",
"label": "third #1.1"
},
{
"value": "whatever",
"label": "third #1.2"
},
{
"value": "unrelated",
"label": "unrelated"
}
]
}]
},
{
"secondData": [{
"thirdData": [{
"value": "another unrelated"
},
{
"value": "whatever",
"label": "third #2"
}
]
}]
}
]
};
const result = data.firstData.reduce((result, first) => {
return first.secondData.reduce((result, second) => {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
return result;
}, result);
}, []);
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
(Same note about filter/map.)