Pass values from observableArray to another without referencing to each other - javascript

I'm trying to pass values from one observableArray to another one without a reference to each other, right know if I change one of the observable array values they synchronize and both have the same value.
Here is jsFiddle
JavaScript:
var test = ko.observableArray([1, 2, 3]);
var test2 = ko.observableArray(test());
test2()[0] = 2;
console.log(test());
console.log(test2());
Output:
[2,2,3]
[2,2,3]
Expected:
[1,2,3]
[2,2,3]

Try doing this:
var test2 = ko.observableArray(test().slice(0));
Instead of this:
var test2 = ko.observableArray(test());
This is a simple way of creating a clone of the underlying array; right now you're referencing the same array.
The slice function basically selects the elements starting at the given index (0 in this case) and ends at the end of the array's length (since it isn't specified) as a new array.
From KnockoutJS:
The slice function is the observableArray equivalent of the native
JavaScript slice function (i.e., it returns the entries of your array
from a given start index up to a given end index). Calling
myObservableArray.slice(...) is equivalent to calling the same method
on the underlying array (i.e., myObservableArray().slice(...)).
Here's an update to your JSFiddle.

Related

Pushing simple value into an array on the fly

I want to be able to create an array with only one value inside of it on the fly without using a variable. This works with a variable:
var arr = [];
arr.push('test');
console.log(arr); // correctly logs ["test"]
But this does not:
console.log([].push('test')); // logs 1
Why does this log 1 instead of ["test"]? Is this coerced into a boolean?
Array.prototype.push returns the new length of the array, not the pushed item nor the array it-self.
"I want to be able to create an array with only one value inside of it
on the fly without using a variable"
const arr = ['test'];
console.log(['test']);
Array.prototype.push()
The push() method adds one or more elements to the end of an array and returns the new length of the array.
In the first example you are first pushing the element in the array then log the array. But in the second example you are logging the returned result of push().

Javascript object properties with same values experience the same changes when they shouldn't (splice)

I'm not sure if this is a bug or if I have a complete misunderstanding of Javascript, but this is what happens:
I take an object with two arrays inside it, one representing the current queue of IDs and another representing the total queue of IDs (hypothetical situation)
var mainObject = {
object1:[],
object2:[]
};
In a function, we set the two property arrays to the same variable which holds the array needed before we can start processing the queue.
var randomVar = [1,2,3,4];
mainObject.object1 = randomVar;
mainObject.object2 = randomVar;
Now we want to make use of the splice method to remove the first index from object1 while keeping it on object two.
mainObject.object1.splice(0,1);
The result of the object is now as follows:
mainObject = {
object1:[2,3,4],
object2:[2,3,4]
};
meaning that both of the properties were spliced when we only asked Javascript to run it once.
See JS Fiddle for live example:
https://jsfiddle.net/ypow6y8g/
Is there something I'm missing or is this just another night spent with loose JS?
You have one array, and two variables whose value is a reference to that array. When you modify the value of one of those variables, you modify the other one as it's the same.
If you want your arrays to be independent, clone one:
var randomVar = [1,2,3,4];
mainObject.object1 = randomVar;
mainObject.object2 = randomVar.slice(); // slice returns a new array

Reversing an array which is a value in object in Javascript

I am trying to reverse an array which is an element in an object.
colorKey = {
"2m":["#ffffff","#000000"]
}
colorKey["2mi"] = colorKey["2m"];
Array.reverse(colorKey["2mi"])
This is not working and returning colorKey["2mi"] the same as colorKey["2m"]. When I run the same command in developer console in browser, it reverses successfully. Where is the problem?
This is no static method off Array called reverse. reverse is an instance method (Array.prototype.reverse) off the Array object, so the instance of the Array must be the caller.
This solves your problem:
colorKey = {
"2m":["#ffffff","#000000"]
}
colorKey["2mi"] = colorKey["2m"];
colorKey["2mi"].reverse();
Output:
["#000000", "#ffffff"]
Calling reverse() for an array mutates it (reverse is in place - a new array is not created). What you want, apparently, is to have a reversed copy of the array. Basically, create a new array with the same values and then reverse it.
var a = [1, 2], b;
b = a.slice(0).reverse();
Slice creates a new array with the same elements (but remember that it is not cloning the elements).
#Rajat Aggarwal
What you are asking for, is to clone your previous array in reverse order.
The only trivial part of it would be reversing it. Because there is no way of cloning Objects and Arrays, nor a general method that you could write down as a function to be using it universally.
This specific array from the sample you provided can be cloned easily because it is flat and it only contains primitives. But the solution to it, will be exactly as specific as the sample array provided.
A specific solution to this task would be to use a plain coma-separated string of successive values and convert that to specific arrays of their corresponding primitive values.:
var colors = "#ffffff,#000000";
var colorKey = {
"2m":colors.split(","),
"2mi":colors.split(",").reverse()
}
which will yield you a:
>> colorKey
{
2m : #ffffff,#000000,
2mi : #000000,#ffffff
}

What does empty array.slice(0).push(anything) mean?

I want to clone a new array from an existing one and push in an element.
Unfortunately, the existing array is an empty one, so it's like:
[].slice().push(65)
the output of above expression is 1.
Why is it 1?
Array#push() returns the length of the resultant array. Since you're pushing a single value onto an empty array, the length of the result will indeed be 1.
If you want to see the updated array as output, you'll need to save a reference to it since push() does not return a reference:
var arr = [].slice();
arr.push(65);
console.log(arr); // [ 65 ]
Changing my comment to an answer:
MDN push(): The push() method adds one or more elements to the end of an array and returns the new length of the array.
You need to do it in two steps, not one with that pattern.
var temp = [].slice();
temp.push(65);
console.log(temp);
If you want to do it in one line, look into concat()
var a = [1,2,3];
var b = [].concat(a,64);
console.log(b);

JavaScript calling array values in two different contexts

I am having trouble understanding how to call specific array values:
I have commented out the questions in the code. Please take a look and let me know why the array produces one result within the function, while producing a different result outside of it. To run the code, please use a website like repl.it
var passengers = [ ["Thomas", "Meeks"],
["Gregg", "Pollack"],
["Christine", "Wong"],
["Dan", "McGaw"] ];
var results = passengers.map(function (array) {
// The following prints out the first names--the entire first column. Why?
console.log(array[0]);
});
console.log(); // Just empty space
// Why is the following only printin the first row of passengers (which it should), but the array[0] printed out the entirety of the first column?
console.log(passengers[0]);
You have an array of arrays, so when you call map here:
var results = passengers.map(function (array) {
// The following prints out the first names--the entire first column. Why?
console.log(array[0]);
});
It's looping through the outer array. The parameter that gets passed into the function is the element of the array that you're looping through, in this case, the inner array. So the console.log(array[0]) is printing the first element of the inner array.
In other words, this code is roughly equivalent to:
console.log(passengers[0][0]);
console.log(passengers[1][0]);
console.log(passengers[2][0]);
console.log(passengers[3][0]);
Notice that in this example, I'm only iterating through the outer array (the first index). The inner array index stays at zero.
But later where you have
console.log(passengers[0]);
It's simply printing the first element from the outer array, which is the entire first inner array.
Further Reading
Array
Array.prototype.map()

Categories

Resources