Updating javascript Array inside object updates all arrays in the object - javascript

I think I am having a bit of a stupid moment here, so hoping you can help.
I have an object discount_arr which holds an associative array of numbers. When trying to update a specific array though, it seems to apply to all the arrays in the object.
Both of these update all the items which is not what I want.
discount_arr.EMAILVIP[0] = 100;
discount_arr[EMAILVIP][0] = 100;
I am sure I am missing something really obvious...
EDIT:
To populate the object I use this code: This loops through another set of data to only pull through unique codes which are used as the array item itself.
var default_days = []; is an array of defaults which I am looking to overwrite. I populate it with a number of 0 values based on days in the month.
var unique = {};
for( var i in data ){
//console.log(data[i]);
for (var j in data[i]){
//console.log(j);
if( typeof(unique[j]) === "undefined"){
discount_arr[j] = default_days;
}
unique[j] = 0;
}
}

The problem is that all of your arrays refer to the same default_days array.
Use discount_arr[j] = [...default_days]; instead to copy array
If you're not using ES6, then
discount_arr[j] = default_days.concat(); should do it

Related

How can I know what object the for is printing in a dictionary in javascript?

I have a dictionary that store associative arrays and is working perfectly, I´am using
sets[SaveNameOfSet]=WordsToSave //WordsToSave is a string array
And I know that if I need to iterate through the dictionary, I need to use this for:
var value;
for (var key in sets)
{
value = sets[key];
console.log(set);
document.getElementById("paragraph").innerHTML=value+"<br>";
}
This shows me each element of every set, but it only prints me the last set, because I dont have the line jumper "\n" but in order for me to use it, I somehow need to know, in that for,what object (array) is printing of the dictionary so, How can I know that?
To finally show something like this:
Setnumber1:={1,2,3,4};
Setnumber2:={5,6,7];
It looks like you have a loop that goes through the sets. Each set is an array. You need an inner loop if you want to do something unique for each element in the set. Below is a sample that may help.
var value;
for (var key in sets)
{
value = sets[key];
setLen=value.length
for (var j=0; j < setLen; j++) {
var innerKey=value[j]; // this should get the inner array value [5,6,7] 5 is value[0], 6 is value[1], etc.
// do something here to capture the inner action
}
ole.log(set);
//document.getElementById("paragraph").innerHTML=value+"<br>";
}

Best way to compare two json arrays and make changes to the position

I have two javascript JSON arrays as follows:
this.BicyclePartsOLD;
this.BicyclePartsNEW;
So basically both have an attribute "ListOrder". The OLD is ordered by ListOrder from 1 to n items.
The NEW one is modified but had the same records as BicyclePartsOLD, so OLD needs to get updated from NEW. If someone changed ListOrder from 1 to 3 in NEW I need to update the OLD list to have that value to 3 and make ListOrder 2 = 1, ListOrder 3 = 2.
I am trying to do it the following way but I am stuck on the best way to set the ListOrder to the new numbers:
for(var i = 0; i < this.BicyclePartsOLD.length; i++)
{
for(var j = 0; j < this.BicyclePartsNEW.length; j++)
{
if(this.BicyclePartsOLD[i].PartNumber === this.BicyclePartsNEW[j].PartNumber)
{
this.BicyclePartsOLD[i].ListOrder = this.BicyclePartsNEW[j].ListOrder;
//NOT Sure how to reorder BicyclePartsOLD here, there will be another
//item with the same ListOrder at this point.
}
}
}
Any advices that would lead me into the correct direction would be much appreciated.
Thinking out of the box, instead of having 2 arrays with the same data but totally unrelated in terms of objects, why not create 2 arrays, both containing the same objects? That way, editing an object makes it look like you're editing it in both places.
First of all, you can have 2 arrays but both point to the same objects:
Array1 -> [{foo:'bar'},{baz:'bam'}]
Array2 -> [{baz:'bam'},{foo:'bar'}]
The object with the foo in the first array can be the same exact object with the foo on the other array (I mean the same object instance, not just because they have the same properties). So editing one will basically look as if they changed in both places.
So with that concept, you can just do a slice() on the NEW array to give you a 1-level copy of the array. Basically, it's the same exact items in a different array container. You can then sort the newly sliced array however you want it.
this.BicyclePartsOLD = this.BicyclePartsNEW.slice().sort(function(){...});
Now to avoid repeatedly slicing like my first solution, I suggest you create both OLD and NEW arrays first. Then when you add an entry, create an object with your data and push that object into both arrays, that way both arrays hold the same object, and editing it will reflect on both arrays.
Something like this:
var OLD = [];
var NEW = [];
// Adding an entry
var newItem = {}
OLD.push(newItem);
NEW.push(newItem);
//Editing that item should reflect on both arrays, since they're the same
OLD[0].someProperty = 'someValue';
console.log(OLD[0].someProperty); // someValue
console.log(NEW[0].someProperty); // someValue
// An item only on OLD
var oldItem = {};
OLD.push(oldItem);
// An item only on OLD
var yetAnotherOldItem = {};
OLD.push(yetAnotherOldItem);
// Let's bring one of those old items to NEW and edit it
NEW.push(OLD[2]);
OLD[2].revived = 'I feel new!';
// Should be in both arrays, but in different indices (since there's the second OLD item)
console.log(OLD[2].revived); // someValue
console.log(NEW[1].revived); // someValue

JS: name/val pairs to array

I'm using a one-off language similar to javascript in syntax, so an answer in that more common language should suffice.
I have a list of name/val pairs that i built from a big GET string that looks something like
"n1=v1,n2=v2..."
I'm not sure that my initial approach is correct. I used a primitive in this language
tolist(GETstring,"=")
to split the name value pairs into the above list. Perhaps, this is the wrong approach from the gate.
This gives me
data = [["n1","v1"],["n2","v2"],...]
I'm trying to change this into a named array, such as
data["n1"]="v1";
data["n2"]="v2";
...
so that I can access items by name, not by list index (as it is highly volitale)
What is the better approach to getting the data in this format. I've tried a few including evals but nothing seems to work.
You'll have to split the string up then iterate through it.
var obj = {};
var originalString = "n1=v1,n2=v2";
var splitOriginalString = originalString.split(",");
for (var i = 0; i < splitOriginalString.length; i++) {
var tmpObj = splitOriginalString[i].split("=");
obj[tmpObj[0]] = tmpObj[1];
}
There is no option to do it. You've got two ways to do workaround.
Create two arrays, one for keys and one for values.
var indexes = ["test", "test2"];
var values = ["val", "val2"];
var value = values[indexes.indexOf("test2")]; // will get "val2"
Create nested array with key 0 for your string key and with 1 for its value.

Which javascript structure has a faster access time for this particular case?

I need to map specific numbers to string values. These numbers are not necessarily consecutive, and so for example I may have something like this:
var obj = {};
obj[10] = "string1";
obj[126] = "string2";
obj[500] = "string3";
If I'm doing a search like this obj[126] would it be faster for me to use an object {} or an array []?
There will be no difference. ECMAScript arrays, if sparse (that is don't have consecutive indices set) are implemented as hash tables. In any case, you are guaranteed the O(n) access time, so this shouldn't concern you at all.
I created a microbenchmark for you - check out more comprehensive test by #Bergi. On my browser object literal is a little bit slower, but not significantly. Try it yourself.
A JS-array is a object, so it should not matter what you choose.
Created a jsperf test (http://jsperf.com/array-is-object) to demonstrate this.
Definetely an object should be the best choice.
If you have such code:
var arr = [];
arr[10] = 'my value';
, your array becomes an array of 11 values
alert(arr.length); // will show you 11
, where first 10 are undefined.
Obviously you don't need an array of length 1000 to store just
var arr = [];
arr[999] = 'the string';
Also I have to notice that in programming you have to chose an appropriate classes for particular cases.
Your task is to make a map of key: value pairs and object is the better choice here.
If your task was to make an ordered collection, then sure you need an array.
UPDATE:
Answering to your question in comments.
Imagine that you have two "collections" - an array and an object. Each of them has only one key/index equal to 999.
If you need to find a value, you need to iterate through your collection.
For array you'll have 999 iterations.
For object - only one iteration.
http://jsfiddle.net/f0t0n/PPnKL/
var arrayCollection = [],
objectCollection = {};
arrayCollection[999] = 1;
objectCollection[999] = 1;
var i = 0,
l = arrayCollection.length;
for(; i < l; i++) {
if(arrayCollection[i] == 1) {
alert('Count of iterations for array: ' + i); // displays 999
}
}
i = 0;
for(var prop in objectCollection) {
i++;
if(objectCollection[prop] == 1) {
alert('Count of iterations for object: ' + i); // displays 1
}
}
​
Benchmark
​
In total:
You have to design an application properly and take into account possible future tasks which will require some different manipulations with your collection.
If you'll need your collection to be ordered, you have to chose an array.
Otherwise an object could be a better choice since the speed of access to its property is roughly same as a speed of access to array's item but the search of value in object will be faster than in sparse array.

storing a dynamic array of values inside an object looped within a for statement

I am looking to create a set of dynamically created arrays stored inside an object. the outcome would be something similar to this...
object.array0.length = 5, object.array1.length = 4, etc
the name of the array would be generated from within a for loop based on a numerical value declared elsewhere in the application.
Here is the code that I have...
var obj = {};
var weekNum = 4;
for(i=0; i < weekNum.length;i++) {
obj['week'+i] = [];
obj['week'+i].push(day);
console.log('days stored in week0: '+obj.week0.length);
}
What seems to be happening is that obj['week'+i] doesn't realize that it is an array, and the push command doesn't seem to be enough to make it think so. So as a resulting value of obj.week0.length is always 1 with the actual value just being replaced each time as opposed to the array being incremented.
Also fyi,
The parameter day in the above code would be passed in from another function representing any chosen day (Mon, Tues, etc)... However, the sequence and the amount of days passed in could differ but will never exceed 5 (m-f).
Looks like a logic problem to me. You're always only inserting 1 day into the array unless day represents something else altogether.
var obj = {};
var weekNum = 4;
// var was missing :)
for(var i = 0; i < weekNum.length; i++) {
// check if entry exists before creating new.
obj['week'+i] = obj['week'+i] || [];
// you're always only inserting 1 value inside the week array
// don't you want to loop through the number of days
// and insert a day entry for *this* week for each day. like this?
// days is another array of, hmm.. days
for(var j = 0; j <days.length; j++) {
obj['week'+i].push(days[j]);
}
console.log('days stored in week0: '+obj.week0.length);
}
It is not changing, because each time through the loop you reset the value to [], then push onto it. Try moving the obj['week'+i] = [] to outside the loop.

Categories