How to store arrays of data in object using JavaScript - javascript

how to store arrays of data in an Object. I tried to store data using
var namelist = [], labelDetails = {};
addedLabels_list.push(name);
labedDetails_list[ownerName] = Address;
namelist holds unique names while labelDetails store data in key value pair
Namelist :
0:"ahmad"
1:"jhon"
2: "hamza"
3: "emma"
labelDetails :
ahmad :"lahore"
jhon :"USA"
hamza :"UK"
emma :"USA, Calforina"
But when same owner name has multiple addresses it won't work.
Let's say Emma live in USA, California and her second address is Washington Dc
and it replaces emma :"washington dc"
var namelist = [], labelDetails = {};
addedLabels_list.push(name);
labedDetails_list[ownerName] = Address;

I would try designing a data structure that also stays stable over time, thus choosing a name based (better id based) key-value person-registry that for each person refers a single data item. This data node then is the root for all person related data that yet will come and then has to be taken care of as well ...
var personRegistry = {
ahmad: {
addressList: ["Lahore"]
},
jhon: {
addressList: ["USA"]
},
hamza: {
addressList: ["UK"]
},
emma: {
addressList: ["USA, California"]
}
}
function storeAddress(name, address) {
var store = personRegistry[name];
if (!store) {
store = personRegistry[name] = {};
store.addressList = [];
}
// prevent address duplicates ...
//if (!store.addressList.includes(address)) { // use that if available.
if (store.addressList.indexOf(address) < 0) {
store.addressList.push(address);
}
}
console.log('personRegistry : ', personRegistry);
storeAddress("emma", 'USA, California');
storeAddress("emma", 'USA, Washington DC');
storeAddress("emma", 'USA, Washington DC');
storeAddress("susan", 'Canada, Toronto');
storeAddress("susan", 'Canada, Toronto');
console.log('personRegistry : ', personRegistry);
.as-console-wrapper { max-height: 100%!important; top: 0; }

For arrays, the key should be unique, so in this case, you can use array to store multiple address for a the same key, this is a start :
function myFunction(){
var namelist = ["ahmad", "jhon", "hamza", "emma"],
labelDetails = {ahmad :["lahore"], jhon :["USA"], hamza :["UK"], emma :["USA, Calforina"]};
labelDetails["emma"].push("washington dc");
console.log(labelDetails);
}
<button onclick="javascript:myFunction()">Click me</button>

You definitely have to make some changes to make your solution work, I would suggest,
labelDetails = {
"ahmad" : ["lahore"],
"jhon" : ["USA"],
"hamza" : ["UK"],
"emma" : ["USA, Calforina"]
};
labelDetails[ownerName].push("washington dc");

Related

Adding an Object to an Array

I'm struggling on adding an Object to an Array (E-commerce context).
My "tc_vars" datalayer is mapped with another datalayer which is called "wa_data". The latter sends the requested information to the first one.
An Object in that case will be a specific product and the Array will be the cart.content property :
var tc_vars = {
nav : {
siteCategory : wa_data.nav.siteCategory,
environment :wa_data.nav.environment,
siteType :wa_data.nav.siteType,
siteName :wa_data.nav.siteName,
pageName :wa_data.nav.pageName,
siteSection :wa_data.nav.siteSection,
country :wa_data.nav.country,
language :wa_data.nav.language,
template :wa_data.nav.template,
doNotTrack :window.navigator.doNotTrack,
customReferrer :wa_data.nav.customReferrer,
genomeID :wa_data.nav.genomeID,
mdmBID :wa_data.nav.mdmBID,
mdmIID :wa_data.nav.mdmIID
},
profile : {
uplayID : readCookie("user_id"),
loginStatus : ''
},
internalSearch : {
searchStatus :wa_data.internalSearch.searchStatus,
searchFilters :wa_data.internalSearch.searchFilters,
searchKeyWord :wa_data.internalSearch.searchKeyWord,
totalResults :wa_data.internalSearch.totalResults,
resultPosition :wa_data.internalSearch.resultPosition,
autoCompletion :wa_data.internalSearch.autoCompletion
},
product : {
productID :wa_data.product.productID,
unitSalePrice :wa_data.product.unitSalePrice,
salePrice :wa_data.product.salePrice,
stockAvailability :wa_data.product.stockAvailability,
salesType :wa_data.product.salesType,
costOfGood :wa_data.product.costOfGood
},
cart : {
orderID:wa_data.cart.orderID,
cartOpen:wa_data.cart.cartOpen,
cartAdd:wa_data.cart.cartAdd,
cartRemove:wa_data.cart.cartRemove,
cartView:wa_data.cart.cartView,
checkout:wa_data.cart.checkout,
purchase:wa_data.cart.purchase,
currency:wa_data.cart.currency,
paymentMethod:wa_data.cart.paymentMethod,
orderShipping:wa_data.cart.orderShipping,
orderTotalAmountDiscounted:wa_data.cart.orderTotalAmountDiscounted,
orderTotalAmountNotDiscounted:wa_data.cart.orderTotalAmountNotDiscounted,
orderTaxAmount:wa_data.cart.orderTaxAmount,
orderDiscountedAmount:wa_data.cart.orderDiscountedAmount,
orderShippingCost:wa_data.cart.orderShippingCost,
billingRegion:wa_data.cart.billingRegion,
billingCity:wa_data.cart.billingCity,
orderStatus:wa_data.cart.orderStatus,
content : [{
productID:'',
name:'',
quantity :'',
promoCode:'',
offerID:'',
salesType:'',
platform :'',
unitSalePrice:'',
salePrice:'',
stockAvailability:'',
lineItemTotalAmountDiscounted:'',
lineItemTotalAmountNotDiscounted:'',
lineItemTaxAmount:'',
lineItemDiscountedAmount:'',
lineItemShippingCost:'',
crossSell:'',
upSell:''
}]
},
tech : {
containerVersion : wa_data.tech.containerVersion
}
}
//Scanning for the content using a loop
if (typeof tc_vars.cart.content !== 'undefined' && tc_vars.nav.pageName === 'Basket'){
for(i=0; i < tc_vars.cart.content.length; i++) {
tc_vars.cart.content[i].productID = wa_data.cart.content[i].productID;
tc_vars.cart.content[i].name = wa_data.cart.content[i].name;
tc_vars.cart.content[i].quantity = wa_data.cart.content[i].quantity;
tc_vars.cart.content[i].promoCode = wa_data.cart.content[i].promoCode;
tc_vars.cart.content[i].offerID = wa_data.cart.content[i].offerID;
tc_vars.cart.content[i].salesType = wa_data.cart.content[i].salesType;
tc_vars.cart.content[i].platform = wa_data.cart.content[i].platform;
tc_vars.cart.content[i].unitSalePrice = wa_data.cart.content[i].unitSalePrice;
tc_vars.cart.content[i].salePrice = wa_data.cart.content[i].salePrice;
tc_vars.cart.content[i].stockAvailability = wa_data.cart.content[i].stockAvailability;
tc_vars.cart.content[i].lineItemTotalAmountDiscounted = wa_data.cart.content[i].lineItemTotalAmountDiscounted;
tc_vars.cart.content[i].lineItemTotalAmountNotDiscounted = wa_data.cart.content[i].lineItemTotalAmountNotDiscounted;
tc_vars.cart.content[i].lineItemTaxAmount = wa_data.cart.content[i].lineItemTaxAmount;
tc_vars.cart.content[i].lineItemDiscountedAmount = wa_data.cart.content[i].lineItemDiscountedAmount;
tc_vars.cart.content[i].lineItemShippingCost = wa_data.cart.content[i].lineItemShippingCost;
tc_vars.cart.content[i].crossSell = wa_data.cart.content[i].crossSell;
tc_vars.cart.content[i].upSell = wa_data.cart.content[i].upSell;
}
}
The problem I'm facing here is that my code is not creating a new object for each new product that is added to the cart content (with all the dedicated properties of the new object).
I've tried using a loop which scans my cart content Array but apparently it's not working (not adding a new object inside the Array). Seems like I'm missing something.
Do you guys have any ideas?
Thx a lot
J
tc_vars.cart.content[i] is undefined. You need to define it first, before filling it up.
for(i=0; i < tc_vars.cart.content.length; i++) {
tc_vars.cart.content[i] = {}; // Creates an empty object
tc_vars.cart.content[i].productID = wa_data.cart.content[i].productID; // Starts filling it
// ....
}
As an alternative (lighter syntax and faster execution), you could also write :
for(i=0; i < tc_vars.cart.content.length; i++) {
tc_vars.cart.content[i] = {
productID : wa_data.cart.content[i].productID,
name : wa_data.cart.content[i].name,
// ....
}
}
But we don't usually add things to an Array by its index. We just push things into it :
for(i=0; i < tc_vars.cart.content.length; i++) {
tc_vars.cart.content.push({
productID : wa_data.cart.content[i].productID,
name : wa_data.cart.content[i].name,
// ....
});
}
This being said, it looks like all you're doing here is copying (not instanciating) wa_data.cart.content into tc_vars.cart.content. So you can completely forget my answer and replace your whole for loop with Gurvinder's answer (+1'd him):
tc_vars.cart.content = JSON.parse(JSON.stringify(wa_data.cart.content));
Unless wa_data already have objects repeated at all the index, following code should work
tc_vars.cart.content = JSON.parse(JSON.stringify(wa_data.cart.content));
You can use an object literal:
tc_vars.cart.content[i] = {
productID: wa_data.cart.content[i].productID,
name: wa_data.cart.content[i].name,
quantity: wa_data.cart.content[i].quantity,
promoCode: wa_data.cart.content[i].promoCode,
offerID: wa_data.cart.content[i].offerID,
salesType: wa_data.cart.content[i].salesType,
platform: wa_data.cart.content[i].platform,
unitSalePrice: wa_data.cart.content[i].unitSalePrice,
salePrice: wa_data.cart.content[i].salePrice,
stockAvailability: wa_data.cart.content[i].stockAvailability,
lineItemTotalAmountDiscounted: wa_data.cart.content[i].lineItemTotalAmountDiscounted,
lineItemTotalAmountNotDiscounted: wa_data.cart.content[i].lineItemTotalAmountNotDiscounted,
lineItemTaxAmount: wa_data.cart.content[i].lineItemTaxAmount,
lineItemDiscountedAmount: wa_data.cart.content[i].lineItemDiscountedAmount,
lineItemShippingCost: wa_data.cart.content[i].lineItemShippingCost,
crossSell: wa_data.cart.content[i].crossSell,
upSell: wa_data.cart.content[i].upSell
}

Filter JSON with unique key/values

I have a JSON object structured as such:
var theSchools = {
Bradley University: "bru",
Knox College: "knox",
Southern Illinois University Edwardsville: "siue",…
}
What I am trying to achieve is a way of retrieving the key, in this case the school name, by supplying the value, the schools 'code.'
It does not appear that I will be able to have this restructured correctly, i.e.
var theSchools = [
{
schoolName:"Bradley University",
schoolCode: "bru"
}
{
schoolName: "Knox College",
schoolCode: "knox"
}
]
so I'm kind of stuck with what I got.
I know the following code is incorrect, but it's essentially what I want to achieve:
if(getParameterByName("schoolId").length>0){
var schoolid = getParameterByName("schoolId");
var schoolName= theSchools.schoolid;
jQuery("h1").after("<h2>Welcome to <strong>"+schoolName+"</strong></h2>")
}
You can use a for...in loop to loop over each property in the object, and return the property name if the value matches:
var theSchools = {
"Bradley University": "bru",
"Knox College": "knox",
"Southern Illinois University Edwardsville": "siue"
};
function findSchool(code) {
for (var s in theSchools) {
if (theSchools[s] === code)
return s;
}
return null;
}
document.getElementById('school').innerText = findSchool('knox');
<div id="school"></div>
The question is if you really need it this way (see answer #James), here's what you requested:
var theSchools = {
"Bradley University": "bru",
"Knox College": "knox",
"Southern Illinois University Edwardsville": "siue"
}, schoolMap = {};
for (var schoolName in theSchools) {
var code = theSchools[ schoolName ];
schoolMap[ code ] = schoolName;
}
document.body.innerHTML = schoolMap["bru"]; // Bradley University
You don't have to use a for loop to check if property exists. Use hasOwnProperty method.
if (theSchools.hasOwnProperty("Knox College")) {
//do stuff
}
Working example: https://jsfiddle.net/7q9czdpc/

nesting multiple level of array with associative

data = [{'name':'John'},
{'name':'Smith'},
{'name':'James'}]
how to format the above array into this
var name = {
"user": {
"name" : [{'name':'John'},
{'name':'Smith'},
{'name':'James'}]
}
}
I tried var name['name'] = data and don't know how to wrap the result. I want to wrap the result with 'user' as it assoc.
You can't assign properties as you create the object. Either first create the object and then set the property:
var name = {};
name.user = { name : data };
or create the entire object at once:
var name = { user: { name: data } };
var data = [{'name':'John'},
{'name':'Smith'},
{'name':'James'}]
var name = {
"user": {
"name" : data
}
}

Finding object in nested collection with Underscore.js

I have a collection of teams (in a league) like so:
var fra1 = {
"sports":[
{
"name":"soccer",
"id":600,
"uid":"s:600",
"leagues":[
{
"name":"French Ligue 1",
"abbreviation":"fra.1",
"id":710,
"isTournament":false,
"country":{
"id":7,
"name":"France",
"abbreviation":"FRA"
},
"uid":"s:600~l:710",
"groupId":9,
"shortName":"Ligue 1",
"teams":[
{
"id":159,
"uid":"s:600~t:159",
"location":"Bordeaux",
"name":"Bordeaux",
"nickname":"Bordeaux",
"abbreviation":"BOR",
"color":"00003e",
},
{
"id":160,
"uid":"s:600~t:160",
"location":"Paris Saint-Germain ",
"name":"Paris Saint-Germain ",
"nickname":"Paris Saint-Germain ",
"abbreviation":"PSG",
"color":"000040",
}
]
}
]
}
],
}
There are about 20 teams in each var stored in this way. Then, I have about six such leagues: eng1, esp1, fra1, ger1, ita1, and usa1. I put those in another collection, like so:
var all = {
"eng1":eng1,
"esp1":esp1,
"fra1":fra1,
"ger1":ger1,
"ita1":ita1,
"usa1":usa1
}
Now, each team (regardless of the league they're in) has a unique ID: in the above example, Bordeaux has ID 159, PSG has ID 160, and so on. So I want to be able to search the all collection for a unique team by teamid, using Underscore.js, but I can't quite get the syntax down. I know I could search one league like so:
var obj = _.find(fra1.sports[0].leagues[0].teams, function(obj) { return obj.id == teamid })
But I can't figure out how to do it across all six leagues. Can anyone help? I'd prefer not to have to combine the collections into one manually, that would be cumbersome with the amount of data involved.
EDIT: I'm currently using:
for (var league in all)
{
var obj = _.find(all[league].sports[0].leagues[0].teams, function(obj) { return obj.id == teamid })
if (obj !== undefined)
{
// do things
}
}
But would still like something nicer.
One solution would be to create a map of the teams with the team id as the key and the team as the value:
var teams = {};
_.each(all, function(nation){
_.each(nation.sports[0].leagues[0].teams, function(team){
teams[team.id] = team;
});
});
You could then access the team using the key:
var psg = teams[160];
As far as parsing the rest of the teams, just use chain:
var allTeams = _.chain(all)
.values()
.pluck('sports').flatten() // once
.pluck('leagues').flatten() // twice
.pluck('teams').flatten() // third time's a charm
.value()
I would recommend using _.groupBy() on teamID. This will give you a hash-table (JS object) that maps teamID -> teamObject. Say you have your teams parsed like this:
var allTeams =[
{
"id":159,
"uid":"s:600~t:159",
"location":"Bordeaux",
"name":"Bordeaux",
"nickname":"Bordeaux",
"abbreviation":"BOR",
"color":"00003e",
},{
"id":160,
"uid":"s:600~t:160",
"location":"Paris Saint-Germain ",
"name":"Paris Saint-Germain ",
"nickname":"Paris Saint-Germain ",
"abbreviation":"PSG",
"color":"000040",
}]
You can group them with:
var lookup = _.groupBy(teams, 'id')
And then look up a team like this:
var myTeam = lookup[teamId]
Simply do additional loops over the sports and leagues, not only over all:
for (var league in all) {
var sports = all[league];
for (var i=0; i<sports.length; i++) {
var leagues = sports[i].leagues;
for (var j=0; j<leagues.length; j++) {
var teams = leagues[j].teams;
// var obj = _.find(teams, function(obj) { return obj.id == teamid })
for (var k=0; k<teams.length; k++) {
var obj = teams[k];
if (obj.id == teamid) {
… // do things
}
}
}
}
}

Look for a value for a given key in JSON and change the value using javascript

I am looking to write a function which can look up a value based on a key and replace that value with another. The key is a tree from the start node of JSON. Here is the example.
var myData = {
name : 'Dan',
address: {
city : 'Santa Clara',
details : {
'prevhouse' : ''
}
}
}
Input to the function is a key tree. For eg, myData-address-details-prevhouse
When I pass this key with a new value, say 'Texas', the prevhouse value will get changed to the new value I am sending.
and new JSON will be
var myData = {
name : 'Dan',
address: {
city : 'Santa Clara',
details : {
'prevhouse' : 'Texas'
}
}
}
Here is what I wrote so far
var tree = key.split("-");
now the tree variable contains ["myData","address", "details","prevhouse"]
I know that we can access the object using myData[tree[0]][tree[1]][tree[2]], but somehow not able to get it dynamic from parsed value.
how do we generate this dynamically since the length of the depth is not known till runtime.
Hope to get a help.
try with this code:
var myData = {
name: 'Dan',
address: {
city: 'Santa Clara',
details: {
prevhouse: ''
}
}
};
function setAttribute(obj, key, value) {
var i = 1,
attrs = key.split('-'),
max = attrs.length - 1;
for (; i < max; i++) {
attr = attrs[i];
obj = obj[attr];
}
obj[attrs[max]] = value;
console.log('myData=', myData);
}
setAttribute(myData, "myData-address-details-prevhouse", "Texas");
here a working jsfiddle demo; see the console for the result
You should be able to iterate through each key because your JSON is just a JS object. So go through each key, check if it's defined, if it is, use that object for your next check. That'll get you where you want to go. Keep in mind you'll be setting the last key to your value.
basic psuedo-code without dealing with setting:
obj = data;
for (key in keys) {
obj = obj[key]
}
Something like this would do:
function update(node, path, value) {
path = path.split('-');
do {
node = node[path.splice(0, 1)];
} while(path.length > 1);
node[path[0]] = value;
}
Given that myData is the object, I think you should be using myData[tree[1]][tree[2]][tree[3]] and throwing away the first item in the array.
Something like this should work recursively (untested)
function updateValue(obj, key, value)
{
var keys = key.split('-');
updateObjectValue(obj, keys.shift(), value);
}
function updateObjectValue(obj, keyArray, value)
{
if (keyArray.length == 1) {
obj[keyArray[0]] = value;
}
else if (keyArray.length > 1) {
updateObject(obj[keyArray[0]], keyArray.shift(), value);
}
}

Categories