Merging two arrays of objects - javascript

I have a bit of a problem where I am struggling on for a pretty long time now. I have two arrays:
var arr1 = [{"x":1,"y":1,"value":null},{"x":2,"y":1,"value":null},{"x":3,"y":1,"value":null},{"x":4,"y":1,"value":null},{"x":5,"y":1,"value":null},{"x":1,"y":2,"value":null},{"x":2,"y":2,"value":null},{"x":3,"y":2,"value":null},{"x":4,"y":2,"value":null},{"x":5,"y":2,"value":null},{"x":1,"y":3,"value":null},{"x":2,"y":3,"value":null},{"x":3,"y":3,"value":null},{"x":4,"y":3,"value":null},{"x":5,"y":3,"value":null},{"x":1,"y":4,"value":null},{"x":2,"y":4,"value":null},{"x":3,"y":4,"value":null},{"x":4,"y":4,"value":null},{"x":5,"y":4,"value":null},{"x":1,"y":5,"value":null},{"x":2,"y":5,"value":null},{"x":3,"y":5,"value":null},{"x":4,"y":5,"value":null},{"x":5,"y":5,"value":null}];
var arr2 = [{"x":1,"y":1,"value":13},{"x":1,"y":3,"value":3},{"x":2,"y":2,"value":146},{"x":2,"y":3,"value":44},{"x":2,"y":4,"value":42},{"x":2,"y":5,"value":5},{"x":3,"y":2,"value":14},{"x":3,"y":3,"value":57},{"x":3,"y":4,"value":23},{"x":3,"y":5,"value":15},{"x":4,"y":2,"value":1},{"x":4,"y":3,"value":4},{"x":4,"y":4,"value":8},{"x":4,"y":5,"value":1},{"x":5,"y":4,"value":1},{"x":5,"y":5,"value":8}];
Where arr1 always contains 25 objects and arr2 contains a variable number of objects, but they are always formatted the same.
How do I combine both arrays into one, where for example:
{"x":1,"y":1,"value":null} from arr1 will be {"x":1,"y":1,"value":13} as a result, but {"x":2,"y":1,"value":null} from arr1 will stay the same, since arr2 does not have this object.
After merging it would be most ideal to have an array of 25 objects, where the field "value" is filled from the objects out of arr2.
EDIT
Alright, since I am getting a lot of downvotes, you can find my code on JSFiddle
Any help is very much appreciated!

You can achieve this using jQuery extend if that's an option.
var extendedArray = $.extend({}, arr1, arr2);
The code above will create a new object for you which will contain what you requested. If you don't want a new object, then just use
$.extend(arr1, arr2);
See the docs mentioned above for more info (like deep extending, etc..).

Related

Clone array of objects into itself

This is my source array (e.g. with 20 elements):
var myArray= $('.my-selector').clone().toArray();
I want to clone the whole array into itself. The new array should have 40 elements (each element is existing "twice"). Like this:
myNewArray = myArray.concat($('.my-selector').clone().toArray())
But it seems that the new arrays elements are references to the original and no real clones.
Updated answer.
#JKB, I have updated my answer based on your recent comment on my old answer. I think the code you have posted in your question is actually working fine. I am using 3 elements to demo this, instead of the original 20, but the same logic applies.
I have quoted you in code comments in the code snippets, from your original question, as well as your recent comment on my old answer. Please read through them.
// "The source are jQuery objects" ~ JKB
var source = $('.my-selector')
/* "This source should be cloned into an array" - JKB
I am Copying this from your original code. */
var myArray = $('.my-selector').clone().toArray()
/* "Now i want to increase the arrays size by copying its content into itself, after that the array should contain 20 objects (each object twice)" - JKB
Our array should contain 6, since we're cloning 3 elements onto itself. Copying this again from your original code. */
var myNewArray = myArray.concat($('.my-selector').clone().toArray())
// "BUT: Now this objects should be inserted back into another DOM place (not into their original place)." - JKB
$('#anotherPlace').append(myNewArray)
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<div class="my-selector">first</div>
<div class="my-selector">second</div>
<div class="my-selector">third</div>
<div id="anotherPlace" style="background:red"></div>
But it seems that the new arrays elements are references to the
original and no real clones.
They aren't, that's why we see 2 copies of each - first, second and third in the red background div. Is this what you were looking for, or did I miss something obvious?
You can use the concat method on javascript from mdn.
The concat() method is used to merge two or more arrays. This method
does not change the existing arrays, but instead returns a new array.
var arr = ["test1", "test2", "test3"];
arr = arr.concat(arr);
hope this helps
using ES6 spread operator you can do:
const arr = [1, 2, 3]
const doubledArr = [...arr, ...arr]
console.log(doubledArr) // [1, 2, 3, 1, 2, 3]
I assume you want the objects to be cloned sequentially, so you could just concatenate the array with a clone of itself using:
arr = arr.concat(arr)

Javascript: Subarrays contain reference to other arrays even though parent is its own array? [duplicate]

This question already has answers here:
How do you clone an array of objects in JavaScript?
(40 answers)
What is the most efficient way to deep clone an object in JavaScript?
(67 answers)
Closed 4 years ago.
OK.
Let me try to say this in some sort of comprehensible manner. I'm an amateur programmer writing my own take on a neural network in javascript. (Without having seen the code for a neural network before)
I was having problems with an array changing when I was trying to change a copy of the array. (Not the original)
I soon realized after rereading what I'd written that when you assign an identifier to an array it doesn't make the identifier a new object with a copy of the array. Instead, it makes a reference to the original array object, for example:
var arr = [1,2,3];
var arr2 = arr;
arr2[0] = 9;
alert(arr);
//Alerts "9,2,3"
With this mind, I googled and found a quick solution:
var arr = [1,2,3];
var arr2 = arr.slice();
arr2[0] = 9;
alert(arr);
//Alerts "1,2,3"
So I changed this in my actual project expecting to see my work completed, but no! I was getting the exact results as before where my array was changing even though it was not supposed to.
After much effort at debugging, I finally worked out that the problem here is that I have a large array of subarrays, which in turn have subarrays.
In code this looks like:
var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];
As you can see, there is one big array that contains 3 smaller arrays, each of which contains two even smaller arrays, each of which contains a number.
In my project, it's more complicated than this and has a couple more layers but this is a decent representation.
So what did I expect to happen?
var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];
var other = arr.slice();
other[0][0][0] = "Uh Oh";
alert(arr);
//Outputs "1,2,3,4,5,6,7,8"
What actually happened?
alert(arr);
//Outputs "Uh Oh,2,3,4,5,6,7,8"
Why does this happen?
How can I fix it?
Thanks in advance.
Try following
var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];
var other = JSON.parse(JSON.stringify(arr));
other[0][0][0] = "Uh Oh";
console.log(arr);
Reasoning
arr.slice() creates different reference for the array, however, any child object/array will still continue to hold the same reference. But you need to change the references of the child object/array as well, for that convert it into a string and then back to object - It will create different references for all the objects.

How to compare two objects

I have a scenario, where I have two different Objects.
Scenario to achieve:
From two objects I need to match the values which has "A1","B2", etc...
Since both the objects values are not in proper order, the loop is breaking and missing some values.
In my demo the object1 has same repeated value i.e. "C3", It should be displayed only once.
Final output required is I need to detect only the matched values from two objects and display its corresponding "a" and "b values."
I have tried almost 90%, but somewhere some minor error is breaking my loop, Please help me out.
Sample code:
for(var i=0;i<obj1.results[0].loc.length;i++){
var findA = obj1.results[0].loc[i].anc[0].title;
for(var j=0;j< obj2.ILoc.length;j++){
var findB = obj2.ILoc[j].ais;
if(findA == findB) {
var a = obj1.results[0].loc[i].a;
var b = obj1.results[0].loc[i].b;
console.log(a);
console.log(b);
}
}
}
This is what I have tried:
Demo Link
I would recommend using for...in loop, since you're using objects instead of arrays.
for (variable in object) {...
}
If length property of both objects is equal, then this kind of loop alone will help you to compare objects with ease.
I would recommend using the diff module. You can use it in node.js and the browser.

Stop the changing of one objects param affecting copies of that object

Say I have multiple arrays.
var array1= [];
var array2= [];
var array3= [];
And I have another array of objects, each with a health parameter.
Say I push the first object in this array into array1, array2 and array3.
Now if I edit the health parameter of array1's object:
array1[0].health -= 50
it changes the health for each arrays object. How can I do it so it only does it for the array im calling into?
If you want a copy of the object in each array, and you don't want the modification of one to affect the others, then you will need to clone the object. The answers on this post will help you with this:
What is the most efficient way to deep clone an object in JavaScript?
Objects in javascript are assigned by reference so if you put the same object into two separate arrays, each array element points at exactly the same object.
If you want separate objects in each array, then you have to explicitly make a new object for the second array (copying properties from the first object if that's what you want).
In jQuery, you can use $.extend() to make a copy of an object. See this answer for two different ways to use it.
Or, in plain Javascript, here's a function that makes a shallow copy of a plain JS object.
function copyObj(src) {
var copy = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
copy[prop] = src[prop];
}
}
return copy;
}
var array1 = []
var array2 = []
array1.health = 50
array2.health = 10
console.log(array1.health)
50
it still remains 50. On the other hand if your question relates to changing array elements as such
var array1= [0,1]
array1[0].health = 50
array1[1].health = 10
console.log(array[0].health) will print out 10 because health is an property of the array object not the element.

Is it possible to chain array.push() in Javascript?

I have 3 separate arrays and I'm looking to load them all into to a single array. Am I able to use .push() several arrays into one? Is something like this possible?
var activeMembers=[]; // Active Users
var noactiveMsg=[]; // Non-Active Users with a Pending Message
var noactiveNomsg=[]; // Non-Active Users without a Pending Message
var chatCenterMembers=[]; // Final Array of Chat Center Members
chatCenterMembers.push(activeMembers).push(noactiveMsg).push(noactiveNomsg);
Is there a way to chain .push()?
You're looking for the (vanilla) JavaScript method Array.concat().
Returns a new array comprised of this array joined with other array(s) and/or value(s).
Example, following your code:
chatCenterMembers = chatCenterMembers
.concat(activeMembers)
.concat(noactiveMsg)
.concat(noactiveNomsg);
chatCenterMembers.push(activeMembers,noactiveMsg,noactiveNomsg)
This question is quite confusing. First of all, the question seems to be asking for a way to combine multiple arrays into one single array containing the elements of all the arrays. However, the accepted answer provides a solution for creating an array of arrays. Since the text in the question suggests merging the elements of multiple arrays into one array while the code example uses push with arrays as arguments, it's quite ambigious what the OP wants.
Furthermore, several answers have suggested using concat. While that fulfills the requirement of returning the resulting array after adding the provided element, and is fine for small sets of data and/or where performance and memory is not an issue, it's inefficient if dealing with large arrays, since each concat operation will allocate a new array, copy all the elements of the old array into it, then copy all the elements of the provided array into it, and dereference the old array (as opposed to simply adding elements to the same array object).
Consider calling concat N times, adding C elements each time:
allocate new array, copy C elements
allocate new array, copy 2 * C elements
allocate new array, copy 3 * C elements
...
A different approach would be to create your own method, either as a separate function or adding it to the Array prototype:
Array.prototype.append = function(e) {
this.push(e);
return this;
}
With this, you could do
[1, 2, 3].append(4).append(5).append(6)
without allocating more than one array object in total.
It could perhaps also be mentioned that with ES2015, the spread operator can be used to add all the elements of an array to another array using push:
const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
arr1.push(...arr2); // arr1 is now [1, 2, 3, 4, 5, 6]
This will however not fulfill the requirement of returning the resulting array for chaining, but the append method above could be used to merge multiple arrays like this:
chatCenterMembers = activeMembers.append(...noactiveMsg).append(...noactiveNomsg);
You can do it instead with .concat().
var chatCenterMembers=[];
chatCenterMembers = chatCenterMembers.concat(activeMembers, noactiveMsg, noactiveNomsg);
Since on one else has posted it:
var chatCenterMembers = activeMembers.concat(noactiveMsg, noactiveNomsg);
push AND unshift chaining
I actually came here looking for both but didn't see any good answer so far for unshift so I'll note that here as well.
push chaining is straight forward
const list = ['hi', 'there']
.concat(['buddy'])
// list is now ['hi', 'there', 'buddy']
but unshift chaining is weird
// need to use concat + map to do unshift chaining
const list = ['hi', 'there']
.concat(['buddy'])
.map((e, i, a) => i == 0 ? a[a.length - 1] : a[i-1])
// list is now ['buddy', 'hi', 'there']
As you can see using map there is a 3rd param given for the array you are using so this gives you power to do all sorts of odd things.

Categories

Resources