Push from one array to another by reference - javascript

Given this fiddle, does anyone have a suggestion as to how I might update the indices of array1? Or more to the point, any idea how to make the indices of array2 references to indices of array1?
http://jsfiddle.net/y8rs56r3/
var array1 = [
{num:"one"},
{num:"two"},
{num:"three"}
];
var array2 = [];
var i = array1.length;
while(i--){
if(i!=1)array2.push(array1[i]);
}
array2[0].num = "one updated";
console.log(array2);
console.log(array1);
Obviously, in this codeblock, array1[0] is not updated.

since your array is set of objects try like this:
var array1 = [
{num:"one"},
{num:"two"},
{num:"three"}
];
var array2 = [];
for(x in array1){
array2.push(array1[x]);
}
array2[0].num = "one updated";
console.log(array2);//output [Object { num="one updated"}, Object { num="two"}, Object { num="three"}]
console.log(array1);// output [Object { num="one updated"}, Object { num="two"}, Object { num="three"}]

Related

Unsplit two arrays Javascript

I have the following code
var Louis = [ 'Louis.IX', 'Louis.VIII' ]
var array1 = [];
var array2 = [];
for (var i = 0; i < Louis.length; i++) {
var split = Louis[i].split(".");
array1.push(split[0]); // before the dot
array2.push(split[1]); // after the dot
}
console.log("Louisname", array1);
console.log("Louisnum", array2);
and the output is
Louisname [ 'Louis', 'Louis' ]
Louisnum [ 'IX', 'VIII' ]
Now any idea on how can i revert the output into the initial array? Please help me, thanks.
You can use .map() with its second index argument to join elements in the first array with the second array by returning a string which contains elements in both arrays like so:
const array1 = ["Louis", "Louis"];
const array2 = ["IX","VIII"];
const original = array1.map((v, i) => `${v}.${array2[i]}`);
console.log(original);
If you're new to JS, here is a more straightforward/imperative way of achieving the same result (see code comments for details):
const array1 = ["Louis", "Louis"];
const array2 = ["IX","VIII"];
const original = [];
for(let i = 0; i < array1.length; i++) { // loop through all elements in array 1
const original_str = array1[i] + "." + array2[i]; // join array element `i` in array1 with array element `i` in array2
original.push(original_str); // add the joined string to the `original` array
}
console.log(original);

copy array of objects

I'm having issues creating a copy of an object array. I can't get the new reference to point to a new independent array.
function OBJ1(name, tags) {
this.myname = name;
this.mytags = tags;
this.myvalue = 0;
}
function OBJ2(arg1) {
this.arg1 = arg1;
this.myarray = [];
}
var OBJ1_array = [];
var result_array2 = null;
var result;
OBJ1_array = createarray1();
for (i = 0; i < 2; i++) {
result = createarray2();
}
function createarray1() {
var myarray = [];
myarray.push(new OBJ1("NAME", [1, 2, 3]));
myarray.push(new OBJ1("others", [1, 2, 3]));
myarray.push(new OBJ1("total", [1, 2, 3]));
return myarray;
}
function createarray2() {
var newarray = $.extend(true, [], OBJ1_array); // newarray should refer to a new array, not the same one as OBJ1_array
OBJ1_array[0].myname = "CHANGED";
console.log("categories", JSON.parse(JSON.stringify(OBJ1_array)));
console.log("newarray", JSON.parse(JSON.stringify(newarray)));
}
Output:
testscript.js:45 categories (3) [{…}, {…}, {…}]0: {myname: "CHANGED", mytags: Array(3), myvalue: 0}1: {myname: "others", mytags: Array(3), myvalue: 0}2: {myname: "total", mytags: Array(3), myvalue: 0}length: 3__proto__: Array(0)
testscript.js:46 newArray (3) [{…}, {…}, {…}]0: {myname: "CHANGED", mytags: Array(3), myvalue: 0}1: {myname: "others", mytags: Array(3), myvalue: 0}2: {myname: "total", mytags: Array(3), myvalue: 0}length: 3__proto__: Array(0)
I expected OBJ1_array[0].myname="CHANGED"; to have no effect on the newly created array newArray.
Things I've tried and didn't work:
var newArray = OBJ1_array.map(a => ({...a}));
var newarray=$.extend(true,[],OBJ1_array);
How can I solve this issue?
The $.extend documentation says the following:
Undefined properties are not copied. However, properties inherited from the object's prototype will be copied over. Properties that are an object constructed via new MyCustomObject(args), or built-in JavaScript types such as Date or RegExp, are not re-constructed and will appear as plain Objects in the resulting object or array.
This means that the array with all plain object in it will be deeply merged/copied. However objects created with the new keyword will not be reconstructed. This leaves us with the following scenario:
The array copy works just fine, however since the elements in the array are created using the new keyword they are not further merged. When altering the array itself (pushing, popping, etc.) you can see that the array is indeed a copy.
The issue here is that you access one of the elements in the array and change the object (created with the new keyword). Both arrays still point to the same object, thus when reading from the other array which hold the same object reference you will also see this change.
To resolve this issue you have to also make a copy of each object in the array. Depending on your use-case you might be able to use Object.assign or Object.create have a look at the documentation before using them blindly.
I've also created a minimal example of the problem you face to give you some better understanding of the issue.
// setup
var array1, array2, array3, array4;
function Dummy(name) { this.name = name }
// test #1 - using plain objects
array1 = [{ name: 'Foo' }];
array2 = $.extend(true, [], array1);
array1[0].name = 'Bar';
console.log(array1[0].name, array2[0].name);
// test #2 - using the `new` keyword
array3 = [new Dummy('Foo')];
array4 = $.extend(true, [], array3);
array3[0].name = 'Bar';
console.log(array3[0].name, array4[0].name);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
The problem is in your loop and OBJ1 function. first time the OBJ1_array is ok but when you come second time its valued already changed..
you can try this code
function OBJ1(name, tags) {
return {myname:name, tags:tags}
//this.myvalue = 0;
}
function OBJ2(arg1) {
this.arg1 = arg1;
this.myarray = [];
}
var OBJ1_array = [];
var result_array2 = null;
var result;
OBJ1_array = createarray1();
for (i = 0; i < 2; i++) {
let tempArr = $.extend(true, [], OBJ1_array);
result = createarray2();
OBJ1_array = tempArr;
}
function createarray1() {
let myarray = [];
myarray.push(new OBJ1("NAME", [1, 2, 3]));
myarray.push(new OBJ1("others", [1, 2, 3]));
myarray.push(new OBJ1("total", [1, 2, 3]));
return myarray;
}
function createarray2() {
let newarray =$.extend(true, [], OBJ1_array);// newarray should refer to a new array, not the same one as OBJ1_array
OBJ1_array[0].myname = "CHANGED";
console.log("categories", JSON.parse(JSON.stringify(OBJ1_array)));
console.log("newarray", JSON.parse(JSON.stringify(newarray)));
}
Updated the answer. Easiest way to achieve what you want is to use JSON.stringify with JSON.parse to create a unlinked copy of array of objects.
const OBJ1 = (name, tags) => ({
myname: name,
mytags: tags,
myvalue: 0,
})
function createarray1() {
var myarray=[];
myarray.push(OBJ1("NAME", [1,2,3]));
myarray.push(OBJ1("others", [1,2,3]));
myarray.push(OBJ1("total", [1,2,3]));
return myarray;
}
const arr = createarray1()
// here you create a copy of array
const newArr = JSON.parse(JSON.stringify(arr))
// apply changes directly to the copy
newArr[0].myname = 'Something else'
console.log(newArr)
console.log(arr)
Arrays and Objects are reference types, which means that when you make a copy by assignment, you are simply copying the reference and not the underlying array/object. In your case, when copying the array, you copy all of the object references, which will still point to the objects in your original array. You need to clone the objects too for it to work.
Use Array.map() to iterate over your array and copy each item.
Use Object.create() to make a shallow clone of each object. This function takes a prototype and property descriptors to create a new object. You can use Object.getPrototypeOf() Object.getOwnPropertyDescriptors() to pass it the prototype and property descriptors of your input object.
function OBJ1(name) {
this.myname = name;
}
const array1 = [new OBJ1("NAME")];
const array2 = array1.map(obj =>
Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
)
);
array2[0].myname = 'Jack';
console.log(array1[0].myname);
console.log(array2[0].myname);
I think you need a deep cloning of your object. please use below function
function clone(src) {
var ret=(src instanceof Array ? [] : {});
for(var key in src)
{
if(!src.hasOwnProperty(key)) { continue; }
var val=src[key];
if(val && typeof(val)=='object') { val=clone(val); }
ret[key]=val;
}
return ret;
}
function OBJ1(name, tags) {
this.myname = name;
this.mytags = tags;
this.myvalue = 0;
}
function OBJ2(arg1) {
this.arg1 = arg1;
this.myarray = [];
}
var OBJ1_array = [];
var result_array2 = null;
var result;
OBJ1_array = createarray1();
for (i = 0; i < 2; i++) {
result = createarray2();
}
function createarray1() {
var myarray = [];
myarray.push(new OBJ1("NAME", [1, 2, 3]));
myarray.push(new OBJ1("others", [1, 2, 3]));
myarray.push(new OBJ1("total", [1, 2, 3]));
return myarray;
}
function createarray2() {
var newarray = clone(OBJ1_array) ; // newarray should refer to a new array, not the same one as OBJ1_array
OBJ1_array[0].myname = "CHANGED";
console.log("categories", JSON.parse(JSON.stringify(OBJ1_array)));
console.log("newarray", JSON.parse(JSON.stringify(newarray)));
}
Much Simpler Approach
var cloneOfOBJ1_array = JSON.parse(JSON.stringify(OBJ1_array));
solved cloning of an array of objects with Object.assign
const newArray = myArray.map(a => Object.assign({}, a));
or even shorter with spread syntax
const newArray = myArray.map(a => ({...a}));

Javascript two array merge( key and value)

I have two array. I want to merge this two arrays into one array. One array consisting keys and another one values.My array looks like
productId = [8,7,9];//Key Element
quantity = ["5","1","3"];//Value Element
//expected new array
newarray = {
"8": 5,
"7": 1,
"9": 3
}
I already tried to merge these arrays, in this way
var newArray = {};
for(var i=0; i< productId.length; i++){
newArray[productId[i]] = quantity [i];
}
console.log(newArray);
It returns
Object [ <7 empty slots>, "5", "1", "3" ]
You are working in firefox so you may get this type of issue because the problem might be caused at how Firefox' console.log has interpreted the input object.
Please look here
Empty slots in JavaScript objects?
Try this
var productId = [8,7,9];
var quantity = ["5","1","3"];
var newarray = {};
productId.forEach((key, i) => newarray[key] = quantity[i]);
console.log(newarray);
Try the following:
var productId = [8,7,9];//Key Element
var quantity = ["5","1","3"];//Value Element
var obj = {};
var i = 0;
for(var k of productId) {
obj[k] = parseInt(quantity[i]);
i++;
}
console.log(obj);
Your new "array" is not an Array but an Object.
You can iterate on one of the arrays using Array.reduce to construct the object.
Something like that:
const arr1 = ['8', '2', '4'];
const arr2 = ['28', '12', '45'];
const result = arr1.reduce((obj, currentItem, index) => {
obj[currentItem] = arr2[index];
return obj;
}, {});
console.log(result);

Javascript 2D array getting each element

I have a 2D array that looks like:
var example = [['Version', 'Number'], [ 'V1.0', 1 ], [ 'V2.0', 2 ]];
I'd like to iterate through the array and take out 'V1.0' and 'V2.0' and store them in their own new array, and do the same for '1' and '2'. I need to break the data up for use with Chart.js
My loop looks like this:
var labels = [];
var data = [];
for (var i=0; i<example.length; i++) {
labels.push = (example[i][0]);
}
for (var j=0; j<example.length; j++) {
data.push = (example[0][j]);
}
I don't know how to properly get either element into their own array for use later.
You can use map to do this, and shift the result in order to remove the first occurence.
var example = [
['Version', 'Number'],
['V1.0', 1],
['V2.0', 2]
];
var result = example.map(e => e[0])
console.log(result);
From what I saw into your example the first pair of elements are the keys for your data, into your example will include them into your final arrays.
This example will generate to a dictionary with the keys Number and Version containing the corresponding values from your array.
var example = [['Version', 'Number'], [ 'V1.0', 1 ], [ 'V2.0', 2 ]];
function extract(items) {
var keys = {},
version = items[0][0],
number = items[0][1];
keys[version] = [];
keys[number] = [];
return items.slice(1).reduce(function(acc, item) {
acc[version].push(item[0]);
acc[number].push(item[1]);
return acc;
}, keys);
}
var result = extract(example);
console.log(result);
From this point you can do something like:
var labels = result.Version;
var data = result.Number;
This looks like what you are trying to achieve:
for(var i=0; i<example.length; i++){
labels.push(example[i][0])
data.push(example[i][1])
}

An array converting question

I have an array below,
var array = {
"Id":[1,2,3],
"Name":["one","two","five"],
"row":[8,9,7]
}
but I want to transform it into
var array2 =
{"data":
[
{"Id":1,"Name":"one","Row:8"},
{"Id":2,"Name":"two","Row:9"},
{"Id":3,"Name":"five","Row:7"},
]
}
Is this possible?
This should do it:
// make sure the new object is initialized
var array2 = { data: [] };
// Count the number of items in array.Id and start iterating
for (var i=0,t=array.Id.length; i < t; i++) {
// Note that array.Id = [1,2,3] does not result in corresponding keys
// array.Id[0] corresponds to value 1!
array2.data.push({
Id: array.Id[i],
Name: array.Name[i],
Row: array.Row[i]
});
}
var array2 = {data: []};
for (i in array.Id) {
array2.data.push({
Id: array.Id[i],
Name: array.Name[i],
row: array.row[i]
});
}
Didn't test it
it's not an array. it's an object.
var myArr = [1,2,3]; //Array definition
var myObj = {test:"1",test2:"2"}; //Object Definition
var array = [1,[1,2,3]]; // multidimensional array

Categories