Creating dynamic objects to a parent object and assigning keys and values? - javascript

I am almost there with this but cannot seem to get this functionality going as planned.
I have two arrays: keyArray and ValArray;
What I am trying to do is to have a function pass two arguments (keyArr,valArr). Within this function, a parent object is declared and a (for-loop) loops through the passed argument's length (in this case "keyArr") creates new objects according the length of the passed argument. And then, the newly created objects are assigned the keys and values.
The issue is that I am able to create the parent object"mObj", and children Objects to "mObj", but am only able to assgin keys and values to the first child object "obj0" not rest of the children objects correctly. At the end of the code, this is what I would like to get:
enter code heremObj.obj0.firstname = John;
mObj.obj0.lastname = superfly;
mObj.obj0.email = "john.superfly#yahoo.com";
mObj.obj1.firstname = John;
mObj.obj1.lastname = superfly;
mObj.obj1.email = "john.superfly#yahoo.com";
mObj.obj2.firstname = John;
mObj.obj2.lastname = superfly;
mObj.obj2.email = "john.superfly#yahoo.com";
This is my code:
var keyArr = ["firstname","lastname","email"];
var valArr = ["John","Superfly","jsuperfly#yahoo.com"];
function test(keys,vals) // FUNCTION TEST ACCEPTS TWO ARGS
{
var mObj = {}; // PARENT OBJECT
var len = (keys.length); //ARGUMENT KEY'S LENGTH
for(var i=0; i<len; i++)
{
mObj["obj" + i] = {}; //CHILDREN OBJECTS ARE CREATED TO PARENT "mObj" OBJECT
mObj["obj" + i][keys[i]] = vals[i]; //KEYS AND VALUES ARE ASSIGNED HERE
}
alert(mObj.obj1.firstname); // CURRENTLY RETURNS "UNDEFINED"
}
test(keyArr,valArr);
Any insight into this would highly be appreciated.
Thank you.

Seems like this is what you need. This code will create as many child objects as the length of keyArr and valArr arrays. Although no idea why you would need it.
var keyArr = ["firstname", "lastname", "email"];
var valArr = ["John", "Superfly", "jsuperfly#yahoo.com"];
function test(keys, vals) {
var mObj = {},
i, j, len = keys.length;
for (i = 0; i < len; i++) {
mObj["obj" + i] = {};
for (j = 0; j < len; j++) {
mObj["obj" + i][keys[j]] = vals[j];
}
}
alert(mObj.obj1.firstname);
}
console.log( test(keyArr, valArr) );​

Related

Issue populating an array of objects dynamically in javascript

I am facing an issue when populating an array of the object dynamically in javascript. I have this sample data as below:
I have to populate following arrays with the data from above:
c1_Arr = [];
c2_Arr = [];
var torontoObj = { arName: 'تورونتو', enName: 'Totonto', value: 0 };
var parisObj = { arName: 'باريس', enName: 'Paris', value: 0 };
var londonObj = { arName: 'لندن', enName: 'London', value: 0 };
Now I am looping through the data to set the values from data as:
var resultCount = results.features.length;
for (var i = 0; i < resultCount; i++) {
var data = results.features[i].attributes;
parisObj.value = data.Paris;
londonObj.value = data.London;
torontoObj.value = data.Toronto;
if (data.Ind_ID === 101) {
c1_Arr.push(parisObj);
c1_Arr.push(londonObj);
c1_Arr.push(torontoObj);
}
}
console.log(c1_Arr);
I am getting this data in console:
Here I am getting the values of the object i.e. Ind_ID = 102 instead of the object values of Ind_ID = 101 (first object).
How to get the values of the required object using the Ind_ID?
The problem is because even though you have the if condition there but you are updating the value of the objects in the loop and since you have already pushed them objects you still have the reference in the main objects. They get overwritten.
Create the 3 objects (torontoObj, etc.) inside the loop.
Reference is getting updated in the second iteration (where Ind_ID is 102)
You should rather do
var resultCount = results.features.length;
for (var i = 0; i < resultCount; i++) {
var data = results.features[i].attributes;
if (data.Ind_ID === 101) {
parisObj.value = data.Paris;
londonObj.value = data.London;
torontoObj.value = data.Toronto;
c1_Arr.push(parisObj);
c1_Arr.push(londonObj);
c1_Arr.push(torontoObj);
}
}
console.log(c1_Arr);
Your object values are getting updated even after being set inside the if loop, simply because, you're not limiting it from being updated.
You could probably do one of the following 2 things:
The simpler one:
Extract the values of Paris, London and Toronto fields of data only if the Ind
_ID is 101.
like this:
var resultCount = results.features.length;
for (var i = 0; i < resultCount; i++) {
var data = results.features[i].attributes;
if (data.Ind_ID === 101) {
parisObj.value = data.Paris;
londonObj.value = data.London;
torontoObj.value = data.Toronto;
c1_Arr.push(parisObj);
c1_Arr.push(londonObj);
c1_Arr.push(torontoObj);
}
}
console.log(c1_Arr);
The more elegant one:
Extract the array element which only matches your condition, in other words filter.
var resultCount = results.features.length;
var data = results.features.filter(feature => feature.attributes.Ind_ID === 101);
parisObj.value = data[0].Paris;
londonObj.value = data[0].London;
torontoObj.value = data[0].Toronto;
console.log(c1_Arr);

Javascript - nested loops and indexes

I am trying to build an array that should look like this :
[
[{"name":"Mercury","index":0}],
[{"name":"Mercury","index":1},{"name":"Venus","index":1}],
[{"name":"Mercury","index":2},{"name":"Venus","index":2},{"name":"Earth","index":2}],
...
]
Each element is the concatenation of the previous and a new object, and all the indexes get updated to the latest value (e.g. Mercury's index is 0, then 1, etc.).
I have tried to build this array using the following code :
var b = [];
var buffer = [];
var names = ["Mercury","Venus","Earth"]
for (k=0;k<3;k++){
// This array is necessary because with real data there are multiple elements for each k
var a = [{"name":names[k],"index":0}];
buffer = buffer.concat(a);
// This is where the index of all the elements currently in the
// buffer (should) get(s) updated to the current k
for (n=0;n<buffer.length;n++){
buffer[n].index = k;
}
// Add the buffer to the final array
b.push(buffer);
}
console.log(b);
The final array (b) printed out to the console has the right number of objects in each element, but all the indexes everywhere are equal to the last value of k (2).
I don't understand why this is happening, and don't know how to fix it.
This is happening because every object in the inner array is actually the exact same object as the one stored in the previous outer array's entries - you're only storing references to the object, not copies. When you update the index in the object you're updating it everywhere.
To resolve this, you need to create new objects in each inner iteration, or use an object copying function such as ES6's Object.assign, jQuery's $.extend or Underscore's _.clone.
Here's a version that uses the first approach, and also uses two nested .map calls to produce both the inner (variable length) arrays and the outer array:
var names = ["Mercury","Venus","Earth"];
var b = names.map(function(_, index, a) {
return a.slice(0, index + 1).map(function(name) {
return {name: name, index: index};
});
});
or in ES6:
var names = ["Mercury","Venus","Earth"];
var b = names.map((_, index, a) => a.slice(0, index + 1).map(name => ({name, index})));
Try this:
var names = ["Mercury","Venus","Earth"];
var result = [];
for (var i=0; i<names.length; i++){
var _temp = [];
for(var j=0; j<=i; j++){
_temp.push({
name: names[j],
index:i
});
}
result.push(_temp);
}
console.log(result)
try this simple script:
var b = [];
var names = ["Mercury","Venus","Earth"];
for(var pos = 0; pos < names.length; pos++) {
var current = [];
for(var x = 0; x < pos+1; x++) {
current.push({"name": names[x], "index": pos});
}
b.push(current);
}

js Array undefined after json declaration

I m new a web developer and i face up the following problem:
"Cannot read property 'length' of undefined"
my code:
var data=();
for(var i;i<parseInt(window.localStorage["numOfInserts"]);i++){
data["category_name"]=localStorage.getItem(("category_name_"+i).toString());
data["category_id"]=localStorage.getItem(("category_id_"+i).toString());
data["provider_name"]=localStorage.getItem(("provider_name_"+i).toString());
data["provider_id"]=localStorage.getItem(("provider_id_"+i).toString());
data["appointment_date"]=localStorage.getItem(("appointment_date_"+i).toString());
data["appointment_time"]=localStorage.getItem(("appointment_time_"+i).toString());
}
$scope.allAppointments=dataArray;
for(var i=0;i<dataArray.length;i++){
$scope.showme[i]=false;
}
After some research I understand that the problem caused to the fact that data is an array but I try to turn it to json, but
var data ={};
gives me the same error as before.
Please Help me
I think this is what you're looking for, see code comments:
// Create an array using []
var data = [];
// Get the count once
var count = parseInt(window.localStorage["numOfInserts"]);
// Be sure to initialize `i` to 0
for (var i = 0; i < count; i++) {
// Create an object to push onto the array, using the information
// from local storage. Note that you don't need toString() here.
// Once we've created the object (the {...} bit), we push it onto
// the array
data.push({
category_name: localStorage.getItem("category_name_"+i),
category_id: localStorage.getItem("category_id_"+i),
provider_name: localStorage.getItem("provider_name_"+i),
provider_id: localStorage.getItem("provider_id_"+i),
appointment_date: localStorage.getItem("appointment_date_"+i),
appointment_time: localStorage.getItem("appointment_time_"+i)
});
}
This does the same thing, it's just more verbose and so could help you understand more clearly what's going on:
// Create an array using []
var data = [];
// Get the count once
var count = parseInt(window.localStorage["numOfInserts"]);
// Be sure to initialize `i` to 0
for (var i = 0; i < count; i++) {
// Create an object to push onto the array
var obj = {};
// Fill it in from local storage. Note that you don't need toString() here.
obj.category_name = localStorage.getItem("category_name_"+i);
obj.category_id = localStorage.getItem("category_id_"+i);
obj.provider_name = localStorage.getItem("provider_name_"+i);
obj.provider_id = localStorage.getItem("provider_id_"+i);
obj.appointment_date = localStorage.getItem("appointment_date_"+i);
obj.appointment_time = localStorage.getItem("appointment_time_"+i);
// Push the object onto the array
data.push(obj);
}
You need to create an array(dataArray before the loop), and create a new object in each iteration and set the property values for that object then add the object to the array like below
var dataArray = [],
data, numOfInserts = parseInt(window.localStorage["numOfInserts"]);
for (var i = 0; i < numOfInserts; i++) {
data = {};
data["category_name"] = localStorage.getItem(("category_name_" + i).toString());
data["category_id"] = localStorage.getItem(("category_id_" + i).toString());
data["provider_name"] = localStorage.getItem(("provider_name_" + i).toString());
data["provider_id"] = localStorage.getItem(("provider_id_" + i).toString());
data["appointment_date"] = localStorage.getItem(("appointment_date_" + i).toString());
data["appointment_time"] = localStorage.getItem(("appointment_time_" + i).toString());
dataArray.push(data)
}
$scope.allAppointments = dataArray;
for (var i = 0; i < dataArray.length; i++) {
$scope.showme[i] = false;
}
It looks like you're trying to create an associative array, so the first line should indeed be
var data = {};
The next part is fine, but then it looks like you want to enumerate the keys
for(var i=0;i<Object.keys(data).length;i++){
$scope.showme[i]=false;
}

Push is overwriting previous data in array

I'm passing a string which looks something like: "John.Doe.100.Newbie-David.Miller.250.Veteran-" to the SplitDatabase function which splits the string appropriately and assigns the values to the UserDataEntry object. The UserDataEntry object is then pushed in to the global UserData array which is supposed to store all the user data.
For some reason though, the UserData.push(UserDataEntry) part seems to be overwriting previous data in the UserData array. The alert in the 1st loop shows the correct data as it loops, but alert in the second loop at the bottom just shows the last record over and over again.
I'm not sure why this is?
var UserData = [];
function SplitDatabase(result) {
var RawUsers = result.split('-');
var UserDataEntry = {};
for (var i = 0; i < (RawUsers.length - 1); i++) {
var tempUserData = RawUsers[i].split('.');
for (var x = 0; x < (tempUserData.length); x++) {
switch (x) {
case 0:
UserDataEntry.firstname = tempUserData[x];
break;
case 1:
UserDataEntry.lastname = tempUserData[x];
break;
case 2:
UserDataEntry.points = tempUserData[x];
break;
case 3:
UserDataEntry.rank = tempUserData[x];
UserData.push(UserDataEntry);
alert(UserData[i].firstname);
break;
}
}
}
for (var i = 0; i < (UserData.length); i++) {
alert(UserData[i].firstname);
}
}
Calling push will not copy your object, because JavaScript Objects are passed by reference: you're pushing the same Object as every array entry.
You can fix this easily by moving the var UserDataEntry = {}; inside the loop body, so that a new object is created each loop iteration:
for (var x = 0; x < (tempUserData.length); x++) {
var UserDataEntry = {};
Put your line var UserDataEntry = {} inside the for loop.
Right now, you only have one object, and you're setting each part of the array to that object. You overwrite the members in your loop.
If you create a new object inside the loop, you'll add all new members in to the array.

JavaScript: convert objects to array of objects

I have thousands of legacy code that stores array information in a non array.
For example:
container.object1 = someobject;
container.object2 = someotherobject;
container.object3 = anotherone;
What I want to have is:
container.objects[1], container.objects[2], container.objects[3] etc.
The 'object' part of the name is constant. The number part is the position it should be in the array.
How do I do this?
Assuming that object1, object2, etc... are sequential (like an array), then you can just iterate through the container object and find all the sequential objectN properties that exist and add them to an array and stop the loop when one is missing.
container.objects = []; // init empty array
var i = 1;
while (container["object" + i]) {
container.objects.push(container["object" + i]);
i++;
}
If you want the first item object1 to be in the [1] spot instead of the more typical [0] spot in the array, then you need to put an empty object into the array's zeroth slot to start with since your example doesn't have an object0 item.
container.objects = [{}]; // init array with first item empty as an empty object
var i = 1;
while (container["object" + i]) {
container.objects.push(container["object" + i]);
i++;
}
An alternate way to do this is by using keys.
var unsorted = objectwithobjects;
var keys = Object.keys(unsorted);
var items = [];
for (var j=0; j < keys.length; j++) {
items[j] = unsorted[keys[j]];
}
You can add an if-statement to check if a key contains 'object' and only add an element to your entry in that case (if 'objectwithobjects' contains other keys you don't want).
That is pretty easy:
var c = { objects: [] };
for (var o in container) {
var n = o.match(/^object(\d+)$/);
if (n) c.objects[n[1]] = container[o];
}
Now c is your new container object, where c.object[1] == container.object1

Categories

Resources