Unexpected result pushing objects into an array - javascript

How to iterate over an array of literal objects in JavaScript?
I would like to do something like that:
grupo = []; // declare array
text = {}; // declare new object
text.a = "texta"; // declare property "a" of an object.
text.b = "textb";
grupo.push(text); // add object to array
text = {}; // declare new object
text.a = "textc"; // declare property
grupo.push(text); // add object with other property
// Iterate over
for (i=0; i<=grupo.length; i++) {
console.dir(grupo[i].text.a);
}

There are various errors in that code:
You're putting the same object in the array twice, not putting two objects in the array. After you push text into the array, you're just overwriting the a property on the same object and pushing it again. You haven't created a new object.
You haven't declared any of your variables (everywhere you've said "declare" in your comments, those are not declarations), so you're falling prey to The Horror of Implicit Globals. Use var to declare variables.
A line comment should start with //, not \\ (those cause a syntax error)
The for loop at the end should use <, not <=, for its termination condition. For the various ways to loop through arrays in JavaScript, see this question and its answers.
Here's a cleaned-up version of that code:
var text, grupo, i; // Declare variables
text = {}; // Create an object and assign it to the variable
grupo = []; // Create an array and assign it to the variable
text.a = "texta"; // Set the property `a` on the object
text.b = "textb"; // Set the property `b` on the object
grupo.push(text); // Put that object onto the array
text = {}; // Create a second object
text.a = "textc"; // Set the property `a` on that new object
grupo.push(text); // Put that object on the array
for (i=0;i<grupo.length;i++) {
// ^-------------------- Note no =
console.dir(grupo[i].text.a);
}

Do you mean something like this?
for (var key in validation_messages) {
var obj = validation_messages[key];
for (var prop in obj) {
// important check that this is objects own property
// not from prototype prop inherited
if(obj.hasOwnProperty(prop)){
alert(prop + " = " + obj[prop]);
}
}
}
Reference: https://stackoverflow.com/a/921808/1054926

groupo[i] is already a text object so you there is an error there. Also, you don't want to look until your index is <= to the length.
Here is a quick look at what you may be looking for in your loop:
for (i=0;i<grupo.length;i++) {
console.log(i,grupo[i].a);
}
However you will have additional problem when you discover that the value of "a" is not what you may be expecting.

Here another possible "solution"
var text = {};
var grupo = [];
text.a = "texta";
text.b = "textb";
grupo.push(text);
text.a = "textc";
grupo.push(text);
for (var i=0;i < grupo.length;i++) {
var x = grupo[i];
if (x && x.a){
console.log(x.a);
} else {
console.log(x);
}
}

Related

Initialize a JavaScript object "tree" to any depth, nested objects

Essentially my I am trying to initialize a JavaScript object and have it contain empty objects with a single key. For example:
getOject('one.two.three')
Would result in the object:
{one:{two:{three:''}}}
As far as I can tell, you can't initialize with dynamic key names unless you use array notation
root[dynamicKey] = 'some variable';
so I need to loop through and based on the number of args initialize each one then assign it's value but the syntax doesn't seem to let me do this in any way that I know of.
So, if it were not a loop it would be like this:
jsonifiedForm[rootKey] = {};
jsonifiedForm[rootKey][childKeys[0]] = {};
jsonifiedForm[rootKey][childKeys[0]][childKeys[1]] = $input.val();
I can't think of a way to do this, I am not typically a JS guy so it might be something simple but I couldn't find anything on Google or Stack Overflow
Thank you in advance!
This function should be what you're looking for.
function getOject(str) {
// this turns the string into an array = 'one.two.three' becomes ['one', 'two', 'three']
var arr = str.split('.');
// this will be our final object
var obj = {};
// this is the current level of the object - in the first iteration we will add the "one" object here
var curobj = obj;
var i = 0;
// we loop until the next-to-last element because we want the last element ("three") to contain an empty string instead of an empty object
while (i < (arr.length-1)) {
// add a new level to the object and set the curobj to the new level
curobj[arr[i]] = {};
curobj = curobj[arr[i++]];
}
// finally, we append the empty string to the final object
curobj[arr[i]] = '';
return obj;
}
Because JavaScript references values in variables instead of copying them "into" variables, we can make our initial value, then make a reference to it which we'll move around as we delve down in:
var getOject = function (k, s) {
// initialize our value for return
var o = {},
// get a reference to that object
r = o,
i;
// we'll allow for a string or an array to be passed as keys,
//and an optional sepeartor which we'll default to `.` if not given
if (typeof k === 'string') {
k = k.split(s || '.');
}
// do we have an array now?
if (k && k.length) {
//iterate it
for (i = 0; i < k.length; i += 1) {
// set a property on the referenced object
r[k[i]] = {};
// point the reference to the new level
r = r[k[i]];
}
}
// send back the object
return o;
}
console.log(getOject('one.two.three'));
console.log(getOject('four|five|six', '|'));
r points to the same thing that o does, initially, and as we move the reference (r) deeper into o and write to it, we're building out o as we go.
The two console.log() calls at the end output the following:
Also notice I let you pass in an array to start with if you feel like it, and made the separator a parameter so that you're not stuck with .

javascript access object with variable name

I am trying to access an object but the name is variable. So:
I have object41, object42 and object43. I want to access object42.
id = 42;
something like this:
object+id.function();
I have searched and found how to assign objects with variable names and how to access properties with variable names but I can't figure out how to access objects with variable names.
Is this something obvious that I am missing?
If these objects are global, you can access them via the window object, and then call your function on the resulting object.
var id = 42;
window["object" + id].function();
Try using eval
// Sample object
function X(id) {
this.value1 = "A" + id;
this.function = function f(value){
alert(value);
};
return this;
}
// n number of object created
var object1 = new X(1);
var object2 = new X(2);
// iterate over all object
for (i=1; i<=2; i++) {
var expr = "object"+i+".function(object"+i+".value1)";
eval(expr);
}
Here a jsfiddle : demo

JavaScript Object Creation and its Prototype

I create an Object in JavaScript:
var object = {value1 : "value1", value2 : "value2"};
If I now try and count the contents of 'object.prototype' I get the result 0. If I add properties I get the correct result. Am I to take it then that 'object.prototype' is in fact empty?
Thanks!
In Javascript, by DEFAULT only "function objects" have a prototype property..
for example, none of the following have a prototype property by default -
var a = new Object();
var b = {};
var a = new Array();
var b = [];
But,
var a = function() {};
has a prototype property.. and by default -
a.prototype is {constructor : this}
If you want to iterate through all the properties you assigned to your object, you can just do it with a for..in loop:
for (var prop in object){
if (object.hasOwnProperty(prop)){
var propValue = object[prop];
// ...
}
}
If you need to count the properties, you can just increment a counter on each iteration.

Building object hierarchy from a 'namespace' string

I'm trying to write a function that takes a string representing a namespace (e.g. "MyCompany.UI.LoginPage") and defines each segment of the namespace as an object if it doesn't already exist. For example, if "MyCompany.UI.LoginPage" wasn't an object, it would evaluate this:
MyCompany = {};
MyCompany.UI = {};
MyCompany.UI.LoginPage = {};
I would like to do this by enumerating each character of the "namespace" (string) argument and defining each object as the enumeration reaches period characters.
How can I enumerate the characters of a string in JavaScript?
You can access the characters of a string directly by its index, using the String.prototype.charAt method:
var str = "foo";
for (var i = 0; i < str.length; i++) {
alert(str.charAt(i));
}
But I don't think that you want to traverse your namespace string character by character, you can use the String.prototype.split method, to get an array containing the namespace levels using the dot (.) character as a separator, e.g.:
var levels = "MyCompany.UI.LoginPage".split('.');
// levels is an array: ["MyCompany", "UI", "LoginPage"]
But I think your question goes further to this, and I will give you a more advanced starting point, I made a recursive function that will allow you to do exactly what you want, initialize several nested object levels using a string:
Usage:
initializeNS('MyCompany.UI.LoginPage');
// that will create a MyCompany global object
// you can use it on an object to avoid globals also
var topLevel = {};
initializeNS('Foo.Bar.Baz', topLevel);
// or
var One = initializeNS('Two.Three.Four', {});
Implementation:
function initializeNS(ns, obj) {
var global = (function () { return this;})(), // reference to the global object
levels = ns.split('.'), first = levels.shift();
obj = obj || global; //if no object argument supplied declare a global property
obj[first] = obj[first] || {}; // initialize the "level"
if (levels.length) { // recursion condition
initializeNS(levels.join('.'), obj[first]);
}
return obj[first]; // return a reference to the top level object
}
You will have to improve this function, for example you will need to sanitize the string...
Convert the string into an array of characters with this code:
var $letterArray = [];
for (var $i = 1; $i <= $yourString.length; $i++)
{
$letterArray[$i] = $yourStringtring.substring(($i - 1), $i);
}
Then you can enumerate over each character in the string array $letterArrary

Remove element from Javascript associative array using array value

I am trying to remove an element from a Javascript associtive array using the value to find it, but I am having trouble. I have tried splice and JQuery's grep method and neither have worked for me. This is what I currently have.
var array_path = new Array();
function bulk_upload(){
var temp_array = new Object();
for (var i = 1; i<8; i++){
temp_array[i] = $('#path' + i).val();
if(temp_array[i]!='' && temp_array[i]!=null){
array_path['path' + i] = $('#path' + i).val();
}
}
process_txt();
}
function process_txt(){
//alert(array_path.indexOf(full_path)); //returns nothing
var removed_element = array_path.splice(getKey(array_path), 1);
//array_path = $.grep(array_path, function(val) { return val != full_path; });
alert(removed_element);//return nothing, just blank alert box
}
function getKey(data) {
for (var prop in data)
return prop;
}
The way to do this is to use the delete operator.
delete array_path[getKey(array_path)]
Some Background Information
In JavaScript, almost everything descends from Object.prototype. JavaScript, being an open and dynamic language allows you to create/modify properties of objects by simple assignment. This is very similar to what an associative array -- a structure that contains keyed values.
Under the hood an array is just an object that descends from Array.prototype with numeric keys and a special property called length. The length property just returns one greater than the highest numeric property. In essence, an Array is an object with different semantics.
If you're wanting an associative array then Array is not the object you want to descend from. You would want to descend directly from Object. There are two ways to do that, you could either use the new operator or an empty object literal. The syntax for both is below:
var o = new Object();
var o = {};
The second is preferred since it's a little bit more concise.
I wrote a blog post about this a while back, have a look if you want a little bit more info.
There is no such thing in JavaScript as an "associative array" per se. The data structure which corresponds to this concept is simply a JavaScript Object.
Of course, a JavaScript Array (like essentially everything in JavaScript) is an Object, but one with additional capabilities. So you can use an Array as a key-value map, but it's really not the correct structure for that.
To remove a key from an Object, you just do something like this:
var myObj = {};
var myKey = "blah";
myObj[myKey] = 1234; // Adds or updates value for "blah" to 1234.
delete myObj[myKey]; // Removes key-value pair for "blah".
Have you tried delete hash.someKey; ?
You can give your object a remove method, or use apply or call to use another object's remove method, if defined.
function myObj(members){
for(var p in members) this[p]= members[p];
}
myObj.prototype.remove= function(val){
for(var p in this){
if(this[p]=== val) delete this[p];
}
return this;
}
myObj.prototype.toString= function(){
var A= [];;
for(var p in this){
if(this.hasOwnProperty(p)){
A.push(p+':'+this[p])
}
}
return '{'+A.join(', ')+'}';
}
var O= new myObj({a: 1, b: 10, c: 100});
alert(O)
O.remove(10);
alert(O)
I'm not psychic, so I can only guess that you wanted to accomplish something like this:
var paths = [];
function getPaths() {
for(var i = 1; i < 8; ++i) {
var value = $('#path' + i).val();
if(value) paths.push(value);
}
}
function process() {
var firstPath = paths.shift();
// do stuff
}
getPaths();
if(paths.length) process();

Categories