This question already has answers here:
JavaScript object: access variable property by name as string [duplicate]
(3 answers)
How to access object using dynamic key? [duplicate]
(3 answers)
Closed 8 years ago.
I need to access object properties with dynamic keys which has persistent structure but different keys, like on one occasion it could be:
var ty_tabs=[{
"key1" :[{
"d1" : "v1",
"d2" : "v2",
"d3" : "v3"
}],
"key2" :[{
"d1" : "v1",
"d2" : "v2",
"d3" : "v3"
}]
}]
and on another one:
var ty_tabs=[{
"key3" :[{
"d1" : "v1",
"d2" : "v2",
"d3" : "v3"
}],
"key4" :[{
"d1" : "v1",
"d2" : "v2",
"d3" : "v3"
}]
}]
How do I adopt my code:
var b,a,d1,d2,d3;
for (b = 0 , a = ty_tabs.length; b < a ; ++b){
d1 = ty_tabs[b].key1[0].d1;
d2 = ty_tabs[b].key1[0].d2;
d3 = ty_tabs[b].key1[0].d3;
}
To access properties with varying keys:
d1 = ty_tabs[b].?[0].d1;
d2 = ty_tabs[b].?[0].d2;
d3 = ty_tabs[b].?[0].d3;
If you don't know about the keys of an object, but need all keys present within an it, you can use Object.keys():
var b,a,d1,d2,d3, i, keys;
for (b = 0 , a = ty_tabs.length; b < a ; ++b){
keys = Object.keys( ty_tabs[b] );
for( i=0; i<keys.length; i++ ) {
d1 = ty_tabs[b][ keys[i] ][0].d1;
d2 = ty_tabs[b][ keys[i] ][0].d2;
d3 = ty_tabs[b][ keys[i] ][0].d3;
}
}
Object.keys() is rather well supported. For older versions of IE, you can use the polyfill provided at MDN
Related
This question already has answers here:
Group array items using object
(19 answers)
Closed 3 months ago.
I have an array which has keys eventId and selectedNumber. In the array same eventid can be present in multiple objects but selectedNumber value will be always different. My aim is to make a nested array in which each object will have unique eventId But selectedNumber will become an array having numbers from each of those objects having the same eventId. I tried using lodash _.groupBy() method but its just combines the objects into array and add it to the value with key as eventId. I don't want that. Anyway to do it?
Input:--
[{
"eventId" : "636939dde9341f2fbbc7256e",
"selectedNumber" : "20"
},
{
"eventId" : "636939dde9341f2fbbc7256e",
"selectedNumber" : "30"
},
{
"eventId" : "63693a55e9341f2fbbc725c0",
"selectedNumber" : "50"
}]
Result:--
[{
"eventId" : "636939dde9341f2fbbc7256e",
"selectedNumber" : ["20", "30"]
},
{
"eventId" : "63693a55e9341f2fbbc725c0",
"selectedNumber" : "50"
}]
let newarr = []
oldArr.map((x,i)=>{
if(i==0){
const numArr = []
numArr.push(x.selectedNumber)
delete x.selectedNumber
x.numArr = numArr newarr.push(x)
}else{
if(oldArr[i].eventId == oldArr[i-1].eventId){
const temp = x.selectedNumber
delete x.selectedNumber
newarr[i-1].numArr.push(temp)
}else{
const numArr = []
numArr.push(x.selectedNumber)
delete x.selectedNumber
x.numArr = numArr
newarr.push(x)
}
}
})
Just reduce your input to an object, and map the object entries to the desired array format:
const input = [{
"eventId" : "636939dde9341f2fbbc7256e",
"selectedNumber" : "20"
},
{
"eventId" : "636939dde9341f2fbbc7256e",
"selectedNumber" : "30"
},
{
"eventId" : "63693a55e9341f2fbbc725c0",
"selectedNumber" : "50"
}];
const result = Object.entries(input.reduce((a, {eventId, selectedNumber}) => {
a[eventId] = a[eventId] || [];
a[eventId].push(selectedNumber)
return a;
}, {})).map(([eventId, selectedNumber]) => ({ eventId, selectedNumber }));
console.log(result);
Instead of creating the intermediate lookup object, you could directly reduce to an array, but it will have a negative impact on the solution's time complexity.
This question already has answers here:
Convert a JavaScript string in dot notation into an object reference
(34 answers)
Closed 3 years ago.
I'm trying to extract some of the fields from a Json response and push them into a Javascript array. I want the selection of the fields to be configurable. Here is what I'm doing:
Consider this as my JSON string:
{
"id" : "1234",
"orderNumber" : "1196",
"createdOn" : "2019-07-02T12:03:39.697Z",
"modifiedOn" : "2019-07-02T12:25:52.126Z",
"testmode" : false,
"customerEmail" : "a#b.com",
"billingAddress" : {
"firstName" : "John",
"lastName" : "Doe",
"address1" : "Wall Street",
"address2" : null,
"city" : "NYC",
"state" : "NY",
"countryCode" : "US",
"postalCode" : "12345",
"phone" : "1122334455"
}
}
Say I want to extract some of the fields (defined in the FIELDS variable) and push them in an array.
# NOTE: the variable `data` here is my json object
var FIELDS = ['id', 'orderNumber', 'customerEmail', 'billingAddress.firstName', 'billingAddress.lastName']
var lineItem = []
# parse the data (my Json object)
for (var i = 0; i < FIELDS.length; i++){
lineItem.push(data[FIELDS[i]])
}
So, this seems to be working OK for the first level (the id, orderNumber and customerEmail) but not for the billingAddress.firstname, etc. This is what I'm wondering about.
My intent is to be able to modify the definition in the FIELDS variable without needing to make any change to the logic in the code.
Hope this makes sense.
Thanks!
As long as there are no periods in the key names this will work.
var data = {
"id" : "1234",
"orderNumber" : "1196",
"createdOn" : "2019-07-02T12:03:39.697Z",
"modifiedOn" : "2019-07-02T12:25:52.126Z",
"testmode" : false,
"customerEmail" : "a#b.com",
"billingAddress" : {
"firstName" : "John",
"lastName" : "Doe",
"address1" : "Wall Street",
"address2" : null,
"city" : "NYC",
"state" : "NY",
"countryCode" : "US",
"postalCode" : "12345",
"phone" : "1122334455"
}
};
var FIELDS = ['id', 'orderNumber', 'customerEmail', 'billingAddress.firstName', 'billingAddress.lastName'];
var lineItem = [];
for (var i = 0; i < FIELDS.length; i++){
let obj = data;
let parts = FIELDS[i].split(".");
while(parts.length) obj = obj[parts.shift()];
lineItem.push(obj)
}
console.log(lineItem);
You just need a function that will split that path on . and traverse the JSON data. With that you can just map() over your fields.
let data = {"id" : "1234","orderNumber" : "1196","createdOn" : "2019-07-02T12:03:39.697Z","modifiedOn" : "2019-07-02T12:25:52.126Z","testmode" : false,"customerEmail" : "a#b.com","billingAddress" : {"firstName" : "John","lastName" : "Doe","address1" : "Wall Street","address2" : null,"city" : "NYC","state" : "NY","countryCode" : "US","postalCode" : "12345","phone" : "1122334455"}}
var FIELDS = ['id', 'orderNumber', 'customerEmail', 'billingAddress.firstName', 'billingAddress.lastName']
// split an traverse
const getFromPath = (path, data) => path.split('.')
.reduce((curr, p) => curr && curr[p], data) // check for curr incase path is undefined
console.log(FIELDS.map(p => getFromPath(p, data)))
The function getFromPath will return undefined if any part of the traversal is not found in the object.
This question already has answers here:
How can I merge properties of two JavaScript objects dynamically?
(69 answers)
Closed 5 years ago.
I would like to combine topData and bottomData into completeData.
var topData = {
"auth": "1vmPoG22V3qqf43mPeMc",
"property" : "ATL-D406",
"status" : 1,
"user" : "test001#aaa.com",
"name" : "Abraham Denson"
}
var bottomData = {
"agent" : "pusher#agent.com",
"agency" : "Thai Tims Agency",
"agentCommission" : 1000,
"arrival" : "arrive 12pm at condo",
"departure" : "leaving room at 6pm",
}
var completeData = topData.concat(bottomData)
Since these are not arrays, concat wont work here.
Can this be done without making foreach loops?
You can use Object.assign() to concatenate your objects.
var newObj = Object.assign({}, topData, bottomData)
From MDN:
The Object.assign() method is used to copy the values of all
enumerable own properties from one or more source objects to a target
object. It will return the target object.
var topData = {
"auth": "1vmPoG22V3qqf43mPeMc",
"property" : "ATL-D406",
"status" : 1,
"user" : "test001#aaa.com",
"name" : "Abraham Denson"
}
var bottomData = {
"agent" : "pusher#agent.com",
"agency" : "Thai Tims Agency",
"agentCommission" : 1000,
"arrival" : "arrive 12pm at condo",
"departure" : "leaving room at 6pm",
}
var completeData = Object.assign({}, topData, bottomData);
console.log(completeData);
You can use Object.assign.
var topData = {
"auth": "1vmPoG22V3qqf43mPeMc",
"property": "ATL-D406",
"status": 1,
"user": "test001#aaa.com",
"name": "Abraham Denson"
}
var bottomData = {
"agent": "pusher#agent.com",
"agency": "Thai Tims Agency",
"agentCommission": 1000,
"arrival": "arrive 12pm at condo",
"departure": "leaving room at 6pm",
}
var completeData = Object.assign(topData, bottomData);
console.log(completeData)
It return the target object which mean properties from bottomData will be added to topData
var completeData = {...topData, ...bottomData};
This is object spread syntax.
I have two objects as follows:
var id="one";
var arrobj = Array[2]
0: Object
name : "a"
desc : "desc1"
1: Object
name : "b"
desc : "desc2"
I am trying to build the object in the following format :
var secondobj = [{ "one" : [{ name:"a",desc:"desc1"},{name:"b",desc :"desc2"}] }]
I tried this :
var secondobj= new Array();
var samplejson = {};
I just gave
samplejson.name = id;
After this I am a bit confused as in how to push values to get the above data structure.
It is a simple as:
samplejson[id]=arrobj;
var arrobj = [{
"name" : "a",
"desc" : "desc1"
},{
"name" : "b",
"desc" : "desc2"
}]
var secondobj = [];
secondobj.push({
one : arrobj
})
console.log(secondobj);
Check this jsfiddle for demo
To make the above structure you can try this:
var secondobj= new Array();
var samplejson = {};
samplejson.one = arrobj;
secondobj.push(samplejson);
console.log(secondobj) // this will give [{ "one" : [{ name:"a",desc:"desc1"},{name:"b",desc :"desc2"}] }]
I have an ng-repeat which returns arrays of objects like the following:
[{"day":"10","title":"day","summary":"summary","description":"ok","_id":"53f25185bffedb83d8348b22"}]
[{"day":"3","title":"day","summary":"summary","description":"ok","_id":"53f25185bffedb83d8348b22"}]
I'd like to have pull out the objects and push them into another array so they are formatted like this:
[
{"day":"10","title":"day","summary":"summary","description":"ok","_id":"53f25185bffedb83d8348b22"},
{"day":"3","title":"day","summary":"summary","description":"ok","_id":"53f25185bffedb83d8348b22"
}]
The goal is to use an orderBy on the array. Is it possible to restructure the JSON into this format and then access the data?
Here is my view for reference:
<div class="calDynamic" data-ng-repeat="n in [] | range:100">
<div ng-repeat="cal in calendar[n].year | filterKey:month">
<p>{{cal}}</p>
</div>
</div>
My JSON format:
{
"_id" : ObjectId("53f252537d343a9ad862866c"),
"year" : {
"December" : [],
"November" : [],
"October" : [],
"September" : [],
"August" : [],
"July" : [
{
"day" : "21",
"title" : "u",
"summary" : "u",
"description" : "ok",
"_id" : ObjectId("53f252537d343a9ad862866d")
}
],
"June" : [],
"May" : [],
"April" : [],
"March" : [],
"February" : [],
"January" : []
},
"__v" : 0
},
{
"_id" : ObjectId("53f252537d343a9ad862866c"),
"year" : {
"December" : [],
"November" : [],
"October" : [],
"September" : [],
"August" : [],
"July" : [
{
"day" : "3",
"title" : "u",
"summary" : "u",
"description" : "ok",
"_id" : ObjectId("53f252537d343a9ad862866d")
}
],
"June" : [],
"May" : [],
"April" : [],
"March" : [],
"February" : [],
"January" : []
},
"__v" : 0
}
Just elaborating my comment to answer:-
You can do this way to merge the arrays scattered across various month to 1 array.
//obj has the the array result that is the input
var temp = [];
var result = temp.concat.apply(temp,obj.map(function(itm){ //Get each object in the source array that hold the year.
return temp.concat.apply(temp, Object.keys(itm.year).map(function(key){ //Get Month for each yeah and flatten it out
return itm.year[key]; //Get day array for each of the month in each year
}));
}));
Object.keys(obj.year) ==> Will give you the months in your property Year to an array
Array.prototype.map ==> You pass in the months array and get back 2D array of days from all of months.
[].concat ==> returns array of concatenated arrays. It can take multiple arrays are argument, so we use function.apply conveniently to convert 2D to 1D.
Bin
Other simple and performance effective way always is loop through and add upon.
Array.prototype.concat allows to join two arrays into one. However, it is just javascript and has nothing to do with Angular, the way to do it is like:
var a = [{"day":"10","title":"day","summary":"summary","description":"ok","_id":"53f25185bffedb83d8348b22"}];
var b = [{"day":"3","title":"day","summary":"summary","description":"ok","_id":"53f25185bffedb83d8348b22"}];
var c = a.concat(b); // returns the concatenated array.