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.
Related
I have two arrays one with label date i.e [Date, Date, Date ...] and
the other with the actual date data i.e [2021-11-26, 2021-11-25, ...].
I want to combine these two arrays such that I get array of objects such as [ { Date: 2021-11-26}, {Date:2021-11-25}, {..}, ...].
I have tried these two methods
obj = {};
for (var i = 0, l = date_label.length; i < l; i += 1) {
obj[date_label[i]] = data_date[i]
}
console.log(obj);
and
_.zipObject(date_label, data_date);
However it only ends up giving me the last date of my data set, in an object data structure ie { Date: 1999-11-24}
The keys inside an object / associative array are unique. Your obj is such a thing. If you turn it into a regular array and push new objects into it, it will work.
const obj = [];
for (let i = 0, l = date_label.length; i < l; i++) {
obj.push({[date_label[i]]: data_date[i]})
}
console.log(obj);
You should probably assert that both your arrays have the same length.
The issues you are facing is that your date_label are the same and the loop are replacing the dates on the same label, again and again, you just need to change the label name and give unique to each one or you change them into the loop as well like this (obj[date_label[i] + str(i)] = data_date[i]).
date_label = ['date1', 'date2', 'date3', .....]
obj = {};
for (var i = 0, l = date_label.length; i < l; i += 1) {
obj[date_label[i]] = data_date[i]
}
console.log(obj);
obj is of type array not object.
data_date needs to be in string format.
for(var i= 0; i<data_date.length-1;i++) {
obj.push({"Date":date_date[i]}) }
with array reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
var myFinalArray = data_date.reduce(
(previousValue, currentValue, currentIndex, array) => ({
currentValue: date_label[currentIndex]
}), {});
Hello AshleyCrasto,
Welcome to Stackoverflow.
Sol : Well, the other members have given solution on how to achieve the desired result. I will emphasize on why you are getting the single object.
it only ends up giving me the last date of my data set, in an object data structure ie { Date: 1999-11-24}
You need to understand how references work in JavaScript. Heres the catch,
As the values in date_label are all same
[Date, Date, Date ...]
When you use,
obj[date_label[i]] = data_date[i]
Everytime, it get executed the same key value will be keep updating instead of creating new key and new value. Because the same values holds same reference.
So, first time {"date" : "somevalue"} will be there, then
second time {"date" : "somevalue2"}, the value of key "date" will be updated
with new value. This is due to same key.
Therefore, you need to take of this thing. For your better understanding here is my code: (same as others but elaborately)
const date_label = ["date","date"]
const data_date = [2021-11-26, 2021-11-25]
function returnObj(label, value){
//this will return a new object with provided label and value.
const Obj = {};
Obj[label] = value
return Obj
}
let listOfObjects = []
for(let i=0 ; i< date_label.length ; i++){
//new object will be added to list.
const obj = returnObj(date_label[i],data_date[i])
listOfObjects.push(obj)
}
console.log(listOfObjects)
I have this Json data I get from server in javascript
var mydata = JSON.parse('["X","Y","Z"]');
Below I have the following data model in javascript..
var mySchemasList = {
schemas: [new SelectSchemaModel("A", false),
new SelectSchemaModel("B", false),
new SelectSchemaModel("C", false)
]
};
I want to create this model dynamically by getting data ('A','B','C') from mydata..
Any help is sincerely appreciated..
Thanks
Can't you just do something like the following?
var i
var mySchemaList = {schemas:[]};
for (i = 0; i < mydata.length; i++) {
mySchemaList.schemas.push( new SelectSchemaModel(mydata[i], false) );
}
In javascript, objects and arrays are accessed using the . or [] operators. The following two lines does exactly the same thing:
mySchemasList.schemas;
mySchemasList['schemas'];
Also, each member of an object or array act like a variable on its own. So you can assign values, objects or arrays to them:
mySchemasList = {};
When a variable (or property) is declared but not assigned anything its value is undefined. So you can check simply by:
if (mySchemasList === undefined) mySchemasList = {};
Alternatively you can use || short circuiting since undefined is considered false:
mySchemasList = mySchemasList || {};
putting this all together, the following two examples does exactly the same thing.
Example 1:
var mySchemasList = {
schemas : []
}
Example 2:
var mySchemasList = {};
mySchemasList.schemas = [];
Now that you've created an array at mySchemasList.schemas you can start pushing other objects into it:
mySchemasList.schemas.push(new SelectSchemaModel("A", false));
mySchemasList.schemas.push(new SelectSchemaModel("B", false));
mySchemasList.schemas.push(new SelectSchemaModel("C", false));
Wrapping it up in a for loop parsing the JSON data, you'd do this:
var mydata = JSON.parse(ajax.responseText);
for (var i=0; i<mydata.length; i++) {
mySchemasList.schemas.push(new SelectSchemaModel(mydata[i],false));
}
I have a class like below;
function Request()
{
this.CompanyId;
this.Password;
this.SessionId;
this.UserId;
this.UserName;
}
I create an object and want to get byte array of object;
var request = new Request();
request.UserName = GlobalProcess.SessionInfo.Server.UserName;
request.Password = GlobalProcess.SessionInfo.Server.Password;
request.CompanyId = GlobalProcess.SessionInfo.SelectedDatabase.CompanyId.toString();
request.UserId = GlobalProcess.SessionInfo.UserId.toString();
request.SessionId = GlobalProcess.SessionInfo.SessionId.toString();
var requestbinary = GetByte(request);
console.log(requestbinary);
My GetByte function is;
function GetByteArrayFromStringArray(parameter)
{
var mainbytesArray = [];
for (var i = 0; i < parameter.length; i++)
mainbytesArray.push(parameter.charCodeAt(i));
return mainbytesArray;
}
In console, I get empty array. What am I doing wrong?
Try this
function GetByteArrayFromStringArray(parameter) {
for (var key in parameter) { // loop through properties
var mainbytesArray = [];
for (var i = 0; i < parameter[key].length; i++)
mainbytesArray.push(parameter[key].charCodeAt(i));
}
return mainbytesArray;
}
It loops through the properties and gets you the array of theese
You're passing an object to a function that expects a string (I think). Your object has no "length" property, so the loop does nothing at all.
You could have the function iterate through the object's properties, I suppose, and accumulate an array from the values of each one. That would not be terribly useful, I don't think, as in JavaScript you're not guaranteed that you'll iterate through an object's properties in any particular order.
In the following code sample i get a strange behavior
var data = ['xxx', 'yyy'];
for (var i in data)
{
var a = i;
var b = data[i];
}
The two first iterations works just fine. I get index "0" and "1" in i, but then it loops one extra time and now the i is "sum". Is this by design or what is this extra iteration used for? The result in my case is always empty and it messes up my code. Is there a way to not do his extra loop?
BR
Andreas
It looks like you (or some other code you've included) have added extra properties onto the Array prototype. What you should be doing is checking to see whether the object you're iterating over actually has that property on itself, not on its prototype:
for (i in data) {
if (data.hasOwnProperty(i)) {
a = i;
b = data[i];
}
}
That said, you should never use for .. in on arrays. Use a regular for loop.
See here for more information: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
You are looping through an Array, not through an Object. For arrays it's better to use:
for (var i=0; i<data.length; i=i+1){
/* ... */
}
In your loop every property of the Array object is taken into account. That makes the for ... in loop for array less predictable. In your case it looks like sum is a property (method) that's added to Array.prototype elsewhere in your code.
There are more ways to loop through arrays. See for example this SO-question, or this one
Just for fun, a more esoteric way to loop an array:
Array.prototype.loop = function(fn){
var t = this;
return (function loop(fn,i){
return i ? loop(fn,i-1).concat(fn(t[i-1])) : [];
}(fn,t.length));
}
//e.g.
//add 1 to every value
var a = [1,2,3,4,5].loop(function(val){return val+1;});
alert(a); //=> [2,3,4,5,6]
//show every value in console
var b = [1,2,3,4,5].loop(function(val){return console.log(val), val;});
Here's a way to safely iterate.
var data = ['xxx', 'yyy'];
for (var i = 0; i < data.length; i++)
{
var a = i;
var b = data[i];
}
What you are getting is an method coming from extending the Array object, I guess you are using some library where is something like
Array.prototype.sum = function () {...};
Perhaps setting data like this would work better: var data = {0:'xxx', 1:'yyy'};
First of all data is an object. Try to add console.log(a); and console.log(b); inside your loop and you'll see.
I would like to create a structure within javascript. I have a pair of informations, I would like to use, example:
array[1] = new Struct();
array[1].name = "parameter-name";
array[1].value = "parameter-value";
array[2] = new Struct();
array[2].name = "parameter-name2";
array[2].value = "parameter-value2";
This can be on a diffrent page with diffrent values, maybe on element within my array, maybe 2-20..
Later, within my generic javascript, I would like to parse the array and continue with my parameters, example:
for(i=1 to length_of_my_array) {
_tag.array[i].name = array[i].value;
}
How can I realize this with pure javascript? Thanks for any hint!
As long as you don't want any fancy features, it's really easy to create such structures in JavaScript. In fact, the code you posted will almost work, if you replace the new Struct() with this:
array[1] = {};
This creates an empty object, and you can put any properties you want in it, such as name and value.
To create an array, you can do something like this:
var array = []; // empty array
// object literal notation to create your structures
array.push({ name: 'abc', value: 'def' });
array.push({ name: 'ghi', value: 'jkl' });
...
And to iterate over the array:
for (var i = 0; i < array.length; i++) {
// use array[i] here
}
It would be good to find out more regarding the problem you are attempting to resolve.
I don't think there is an object in JavaScript called Struct, unless you define one.
I think what you are looking for is a JavaScript object instead of Struct. There are a number of ways to create a new object, and they can be nested in an array or in other objects.
myArray[0] = new Object();
myArray[0].name = "parameter-name";
myArray[0].value = "parameter-value";
myArray[1] = new Object();
myArray[1].name = "parameter-name2";
myArray[1].value = "parameter-value2";
Notice that I have changed your code in a couple of ways:
1. "array" is named "myArray" to clarify that we are referring to a particular array.
2. The first instance of myArray is 0. Arrays start at 0 in Javascript.
3. Struct is changed to Object.
myarray = [
{
"name":"parameter-name",
"value":"parameter-value"
},
{
"name":"parameter-name2",
"value":"parameter-value2"
}
];
This is an alternative syntax for doing the same thing. It uses "literal notation" to designate an array (the square brackets), and the objects (the curly brackets).
for(var i = 0; i < myArray.length; i++) {
for(key in myArray[i]) {
alert(key + " :: " myArray[i][key]);
}
}
This will loop over the array and alert you for each property of the object.
alert(myArray[0]['value']) //parameter-value
myArray[0]['value'] = "bar";
alert(myArray[0]['value']) //bar
Each property of each object can also be assigned a new value.
You can define arrays and generic objects in pure JavaScript/json:
var array = []; // empty array
array.push({name: 'parameter-name', value: 'parameter-value'});
array.push({name: 'parameter-name2', value: 'parameter-value2'});
console.log(array);
// Output:
// [Object { name="parameter-name", value="parameter-value2"}, Object { name="parameter-name2", value="parameter-value2"}]
You can also define the same array like so:
var array = [
{name: 'parameter-name', value: 'parameter-value'},
{name: 'parameter-name2', value: 'parameter-value2'}
];
As far as looping through the array:
for (var i = 0; i<array.length; i++) {
var elem = array[i];
console.log(elem.name, elem.value);
}
// Outputs:
// parameter-name parameter-value2
// parameter-name2 parameter-value2
I'd store object literals in the array, like so:
var myArray = [];
myArray[0] = {name:"some name", value:"some value"};
myArray[1] = {name:"another name", value:"another value"};
for (i=0; i < myArray.length; i++) {
console.log(myArray[i].name + ' / ' + myArray[i].value);
}
// initialize empty array
var myArray = [];
// fill it with an object - the equivalent of a struct in javascript
myArray.push({
name: 'example-name'
value: 'example-value'
});
// repeat as neccessary
// walking through the array
for (var i = 0; i < myArray.length; i++)
{
// retrieving the record
record = myArray[i];
// and accessing a field
doSomething(record.name);
}
var array = {paramName: 'paramValue', paramName2: 'paramValue2'};
for(i in array) {
_tag.i = array.i;
}
There is no "Struct" in JavaScript only Object
my_array = new Array();
my_array.push({name: 'john', age:31});
my_array.push({name: 'da_didi', age:120});
for (i=0; i<my_array.length; i++)
{
alert(my_array[i].name);
}
How about
function Struct(name, value) {
this.name = name;
this.value = value;
}
arr[0] = new Struct("name1", "value1");
Javascript objects are loose objects: properties can be added and removed dynamically. So making a new Struct(), as you suggest, does -not- guarantee that the returned object will always have the properties you expect it to have. You have to check the availability of properties at the point of usage (duck typing):
var i, element;
for (i = 0; i < array.length; i++) {
element = array[i];
if (Object.hasOwnProperty.call(element, "name")
&& Object.hasOwnProperty.call(element, "value")) {
_tag[element.name] = element.value;
}
}
(Also, I'm just guessing that _tag is an object itself, but that wasn't clear from your example.)
You could probably use a more succinct syntax, but that depends heavily on the values of the properties. For example, you -might- be able to use something like this:
var i, element;
for (i = 0; i < array.length; i++) {
element = array[i];
if (element.name && element.value) {
_tag[element.name] = element.value;
}
}
But you need to realize that the above condition will be false not only if one or both of the properties (name and value) are undefined but also if the value of either or both refers to the empty string, null, 0, NaN, or false.