Adding something to the top of a JSON object - javascript

I have a JSON object which is initiated when the page is loaded, like this:
data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;
Is there a way to inject an element before the first foo element, so that when doing a for var i in data, the new element will be looped through before the elements that were added when the object was initiated?
The reason is, I'm displaying some items to the user. When the user adds a new item via javascript, I want this new item to be displayed above all the existing items, however when I add the new item, i.e
data[newItem] = newItem;
Then the JSON object looks like this:
data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;
data[newItem] = newItem;
Instead of how I want, which is:
data[newItem] = newItem;
data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;
Any ideas?

In JS, object properties' order is not guaranteed. Therefore, even if they are ordered in the JSON string, when parsed as a JS object, you will never predict in what order they come up.
Better use arrays instead. You could use the unshift() method to put the item in the first index.
var data = [bar,bar2,bar3];
data.unshift(newItem);
//data = [newItem,bar,bar2,bar3];

As a compliment to Joseph the Dreamer's answer, I have ran some quick checks in firefox & chrome.
Firefox:
var obj = {};
obj.a = 'a';
obj.c = 'c';
obj.b = 'b';
obj['0'] = '0';
for(var i in obj){
console.log(i);
}
//prints:
a
c
b
0
Chrome:
var obj = {};
obj.a = 'a';
obj.c = 'c';
obj.b = 'b';
obj['0'] = '0';
for(var i in obj){
console.log(i);
}
//prints:
0
a
c
b

I've stumbled upon this and achieved it using:
const newObject = Object.assign({first: value}, oldObject)
As mentioned, order is not guaranteed but for me this is good enough. :)

Is there a way to inject an element before the first foo element?
Which comes first in the array:
window.object or window.alert?
Neither, objects don't have an order. If you want an array use an array. Objects are not arrays.
If you want
var ThingsInOrder = [
FirstThing,
SecondThing,
ThirdThing
];
ThingsInOrder.push(ForthThing);
Use an array.
If you want:
var ThingsNeverInOrder = {
Window,
Alert,
Derp,
Herp
};
ThingsNeverInOrder.foo = bar;
Use an object.

Instead of adding new value in the same object, you can create a new object and arrange properties order as you want.
example :
var objj1 = {name:'viru',lastname:'nehra'};
So create a new object with new property which you want on top:
var obj2 = {age: 21}
and the run:
for(var key in objj1){
obj2[key] = objj1[key]
}
obj2 = {age: 21, name: "viru", lastname: "nehra"}

I think you can convert it to string, append your data at the beginning of the string then re-convert the string to json using "eval"

Related

push Object in array in $.each

Maybe I'm just blind, but I'm struggling for a good amount of time now:
I have a small piece of JS-Code here:
var linkInput = $('#Link input.gwt-TextBox').val();
var parentRow = $('#Link').parent().parent();
var links = linkInput.split("|");
// hide text-input
$(parentRow).hide();
// get rid of empty elements
links = links.filter(Boolean);
var aSites = [];
var oSite = {};
$(links).each(function (k, v) {
splits = v.split(".");
domainName = splits[1];
oSite.name = domainName;
oSite.url = v;
aSites.push(oSite);
});
console.log(aSites);
To specify: Get the value of an input-field, hide the row afterwards and save all the values in an object, which is then pushed into an array.
The parameter, taken from the console-tab of google Chrome:
var links = ["www.myshop1.de/article/1021581", "https://www.myshop2.de/article/1021581"] [type: object]
I thought, I iterate through all elements of this object (in that case 2 times), push the values into an object and the object into an array, to have access to all of them afterwards.
At some point however, I seem to override my former values, since my output looks like this:
0: {name: "myshop1", url: "https://www.myshop1.de/1021581"}
1: {name: "myshop2", url: "https://www.myshop2.de/1021581"}
length: 2
__proto__: Array(0)
Where is my mistake here? Is there a smarter way to realize this?
On a sidenote:
I tried to use only an array (without adding an object), but it seems like I
can't use an associative key like this:
var myKey = "foo";
var myValue = "bar";
myArray[myKey] = myValue
You should move this:
var oSite = {};
...inside the each callback below it, because you need a new object in each iteration.
Otherwise you are mutating the same object again and again, pushing the same object repeatedly to the aSites array, which ends up with multiple references to the same object.
Not related, but you can use $.map to create your array (or vanilla JS links.map()):
var aSites = $.map(links, function(v) {
return { name: v.split(".")[1], url: v };
});

How to add another entry at the beginning of this JSON data? [duplicate]

I have a JSON object which is initiated when the page is loaded, like this:
data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;
Is there a way to inject an element before the first foo element, so that when doing a for var i in data, the new element will be looped through before the elements that were added when the object was initiated?
The reason is, I'm displaying some items to the user. When the user adds a new item via javascript, I want this new item to be displayed above all the existing items, however when I add the new item, i.e
data[newItem] = newItem;
Then the JSON object looks like this:
data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;
data[newItem] = newItem;
Instead of how I want, which is:
data[newItem] = newItem;
data[foo] = bar;
data[foo2] = bar2;
data[foo3] = bar3;
Any ideas?
In JS, object properties' order is not guaranteed. Therefore, even if they are ordered in the JSON string, when parsed as a JS object, you will never predict in what order they come up.
Better use arrays instead. You could use the unshift() method to put the item in the first index.
var data = [bar,bar2,bar3];
data.unshift(newItem);
//data = [newItem,bar,bar2,bar3];
As a compliment to Joseph the Dreamer's answer, I have ran some quick checks in firefox & chrome.
Firefox:
var obj = {};
obj.a = 'a';
obj.c = 'c';
obj.b = 'b';
obj['0'] = '0';
for(var i in obj){
console.log(i);
}
//prints:
a
c
b
0
Chrome:
var obj = {};
obj.a = 'a';
obj.c = 'c';
obj.b = 'b';
obj['0'] = '0';
for(var i in obj){
console.log(i);
}
//prints:
0
a
c
b
I've stumbled upon this and achieved it using:
const newObject = Object.assign({first: value}, oldObject)
As mentioned, order is not guaranteed but for me this is good enough. :)
Is there a way to inject an element before the first foo element?
Which comes first in the array:
window.object or window.alert?
Neither, objects don't have an order. If you want an array use an array. Objects are not arrays.
If you want
var ThingsInOrder = [
FirstThing,
SecondThing,
ThirdThing
];
ThingsInOrder.push(ForthThing);
Use an array.
If you want:
var ThingsNeverInOrder = {
Window,
Alert,
Derp,
Herp
};
ThingsNeverInOrder.foo = bar;
Use an object.
Instead of adding new value in the same object, you can create a new object and arrange properties order as you want.
example :
var objj1 = {name:'viru',lastname:'nehra'};
So create a new object with new property which you want on top:
var obj2 = {age: 21}
and the run:
for(var key in objj1){
obj2[key] = objj1[key]
}
obj2 = {age: 21, name: "viru", lastname: "nehra"}
I think you can convert it to string, append your data at the beginning of the string then re-convert the string to json using "eval"

Strange behaviour of array in double for loops - JavaScript

I have rootObject which holds childObject as a value. I use two for loops to get values from childObject and put them to array. Array is cleared in every iteration of outer loop.
var childObject = new Object();
for (var i = 0; i < 3; ++i) {
childObject[i] = i*i;
}
var rootObject = new Object();
rootObject[0] = childObject;
I am using console.log(resultArray) to observe array. And this is what I got:
When clearing before second for loop
var resultArray = []
for ( var rootKey in rootObject){
resultArray.length = 0; //clearing array
for ( var childKey in rootObject[rootKey]){
resultArray.push([ parseInt(childKey), rootObject[rootKey][childKey] ]);
}
console.log(resultArray);
}
I get [Array[2], Array[2], Array[2]
When clearing after second for loop
var resultArray = []
for ( var rootKey in rootObject){
for ( var childKey in rootObject[rootKey]){
resultArray.push([ parseInt(childKey), rootObject[rootKey][childKey] ]);
}
console.log(resultArray);
resultArray.length = 0; //clearing array
}
I get []
Why result is different?
EDIT
I am using Firefox 29
http://jsfiddle.net/xf78k/5/ <-- good
http://jsfiddle.net/xf78k/6/ <-- bad
You store a reference to the array into your var, and print it through the console, that will show you the realtime (dynamic) state of the array.
In other words, the console will show you three times the same objects, in both cases, and its state will be the final state of resultArray.
If you converted it to string, or printed its length, you'd have the expected result, because it would be a primitive value, and the console wouldn't keep track of its reference.
Taste the difference:
var childObject = new Object();
for (var i = 0; i < 3; ++i) {
childObject[i] = i*i;
}
var rootObject = new Object();
rootObject[0] = childObject;
var resultArray = []
for ( var rootKey in rootObject){
for ( var childKey in rootObject[rootKey]){
resultArray.push([ parseInt(childKey), rootObject[rootKey][childKey] ]);
}
console.log(resultArray.length);
resultArray.length = 0; //clearing array
}
One suggestion: don't initialize plain objects with "new Object()".
var childObject = {};
is to be preferred instead.
EDIT: why you'd rather prefer the literal syntax to init objects
Try this code:
var a = new Object(1);
var b = new Object("1");
The result is that a is a Number(), and b is a String, because Object accept an optional parameter that drives which constructor is used for the object.
So, it is error prone.
Now try this:
Object = function () {
//xmlhttp=new XMLHttpRequest("malicious site"); ...
console.log("XSS attack")
}
var c = new Object();
any script can override it, while {} is safer.
Finally, due to JS engines optimization, the literal syntax leads to better performance.
More
console.log does lazy and async evaluation of variables. Since arrays are passed by reference, it's not strange for it to reflex the value it has after clearance.
If you insert a breakpoint before clearing you should see the array with its elements.

Randomly select enumerable property of object in Javascript

Given a dictionary-like object in Javascript such as {a:1, b:-2, c:42}, is there a simple way to randomly choose a property?
In the above example, I would like to have a function that would return a, b or c randomly.
The solution I've come up with is like the following:
var proplist = []
forEach(property in foo) {
if(propertyIsEnumerable(foo[property]) {
proplist.push(property);
}
}
var n = proplist.length;
// randomly choose property (randInt(n) returns a random integer in [0,n))
proplist[randInt(n)];
Is there a more idiomatic way to do this?
Use Object.keys (or even Object.getOwnPropertyNames) to get a list of all properties. Then, select a random property by multiplying Math.random() with the length of the list, floored.
var propList = {}; //...
var tmpList = Object.keys(propList);
var randomPropertyName = tmpList[ Math.floor(Math.random()*tmpList.length) ];
var propertyValue = propList[randomPropertyName];
This can be quite idiomatic with underscore.js:
randomProp = _.shuffle(_.keys(obj))[0]
Edit: actually, one should use _.sample for that.
Or if you want to write a reusable function for this, you could do
const randomFrom = list => list[Math.floor(list.length * Math.random())];
const randomProp = obj => randomFrom(Object.keys(obj));
randomProp(propList); //=> one of the keys of propList
This will return undefined if your object has no properties, but that's probably the best we could do in any case.

javascript push multidimensional array

I've got something like that:
var valueToPush = new Array();
valueToPush["productID"] = productID;
valueToPush["itemColorTitle"] = itemColorTitle;
valueToPush["itemColorPath"] = itemColorPath;
cookie_value_add.push(valueToPush);
the result is [];
what am i do wrong?
Arrays must have zero based integer indexes in JavaScript. So:
var valueToPush = new Array();
valueToPush[0] = productID;
valueToPush[1] = itemColorTitle;
valueToPush[2] = itemColorPath;
cookie_value_add.push(valueToPush);
Or maybe you want to use objects (which are associative arrays):
var valueToPush = { }; // or "var valueToPush = new Object();" which is the same
valueToPush["productID"] = productID;
valueToPush["itemColorTitle"] = itemColorTitle;
valueToPush["itemColorPath"] = itemColorPath;
cookie_value_add.push(valueToPush);
which is equivalent to:
var valueToPush = { };
valueToPush.productID = productID;
valueToPush.itemColorTitle = itemColorTitle;
valueToPush.itemColorPath = itemColorPath;
cookie_value_add.push(valueToPush);
It's a really fundamental and crucial difference between JavaScript arrays and JavaScript objects (which are associative arrays) that every JavaScript developer must understand.
Use []:
cookie_value_add.push([productID,itemColorTitle, itemColorPath]);
or
arrayToPush.push([value1, value2, ..., valueN]);
In JavaScript, the type of key/value store you are attempting to use is an object literal, rather than an array. You are mistakenly creating a composite array object, which happens to have other properties based on the key names you provided, but the array portion contains no elements.
Instead, declare valueToPush as an object and push that onto cookie_value_add:
// Create valueToPush as an object {} rather than an array []
var valueToPush = {};
// Add the properties to your object
// Note, you could also use the valueToPush["productID"] syntax you had
// above, but this is a more object-like syntax
valueToPush.productID = productID;
valueToPush.itemColorTitle = itemColorTitle;
valueToPush.itemColorPath = itemColorPath;
cookie_value_add.push(valueToPush);
// View the structure of cookie_value_add
console.dir(cookie_value_add);

Categories