How to merge 2 Objects taken by input's val - javascript

I have two JSON objects and I want to merge them:
Object1: {"9":{"322":{"option0":"177"}}}
Object2: {"10":{"323":{"option":"456"}}}
And I want for final result to be like:
{
"9": {
"322": {
"option0": "177"
}
},
"10": {
"323": {
"option": "456"
}
}
}
I tried the concat method, but the result is this:
{
"9":{
"322":{
"option0":"177"
}
}
}
{
"10":{
"323":{
"option":"456"
}
}
}
PS: The objects are taken by input like so:
var object1 = $('input').val();

Use Object.assign()
const Array1 = {"9":{"322":{"option0":"177"}}}
const Array2 = {"10":{"323":{"option":"456"}}}
let newObject = Object.assign({}, Array1, Array2);
console.log(newObject);

ES6 way:
const object1 = {"9":{"322":{"option0":"177"}}}
const object2 = {"10":{"323":{"option":"456"}}}
const object3 = { ...object1, ...object2 }
console.log(object3)
Codepen:
https://codepen.io/anon/pen/eLxBdK?editors=0001
Use ES6 syntax whenever possible.
shorter code
more readable usually
this case in particular allows you to easily do deep merges (which was a pain before)
faster

Since you are getting the values from a text field, they will initially be JSON strings. In order to treat them like objects and merge then you need to parse them first. Then you can achieve your desired output using jQuery's $.extend() method, which merges one object into another.
Demo:
var obj1 = JSON.parse($("#obj1").val());
var obj2 = JSON.parse($("#obj2").val());
var merged= $.extend({}, obj1, obj2);
console.log(merged);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="obj1" value='{"9":{"322":{"option0":"177"}}}'/>
<input type="text" id="obj2" value='{"10":{"323":{"option":"456"}}}'/>
Documentation: https://api.jquery.com/jquery.extend/

Actually these are objects and not JSON Arrays, and you got an array as result because Array#concat() will return an array and what you want is an object.
So what you can do is to use Object.assign() method:
let obj = Object.assign({}, JSON.parse(o1), JSON.parse(o2));
Note:
If you take these objects from input, you will be getting them as strings you need to parse them with JSON.parse() to getb the right objects.
let o1 = '{"9":{"322":{"option0":"177"}}}';
let o2 = '{"10":{"323":{"option":"456"}}}';
let obj = Object.assign({}, JSON.parse(o1), JSON.parse(o2));
console.log(obj);

Related

How to merge multiple JSON objects to one single json object in javascript

My requirement is to get the json objects from different sources and merge them into one single json object using javascript
example:
Below there are 2 json objects with different values and I want to make it as one final Json object and append new value to the final result
json1= {
"b":"test1",
"a":"test3",
"type":"sample1"
}
json2= {
"endDate":"ddd1",
"startDate":"dd01"
}
Expected results should be like below
result = {
"b":"test1",
"a":"test3",
"type":"sample1",
"endDate":"ddd1",
"startDate":"dd01"
}
Can anyone suggest me the best way to achieve this in javascript please ?
You can use the rest operator to remove type property and then assign values from 1st object to new property of the merged object
let mergeObjects = (a, b) => {
let {type, ...rest} = b; //remove type property
for(let prop in rest){
if(a[prop]){
rest[prop].xyz = a[prop];
}
}
return rest;
}
let Object3= mergeObjects(Object1, Object2);
console.log(Object3);
Can be as simple as this:
let Object1 ={"b":"test1","a":"test3","type":"sample1"};let Object2 ={"b":{"endDate":"ddd1","startDate":"dd01"},"a":{"endDate":"31","startDate":"01"},"type":"sample2"}
let Object3 = Object2;
for (let i in Object3){
Object3[i]["XYZ"] = Object1[i]
}
Object3["type"] = "12345"
console.log(Object3)

transform array to dynamic object

I would like to transform the following array which is dynamic to an dynamic object
e.g.
let
array=[{"MyFirstValue":"1"},{MySecondvalue:"2"}]
I would like to convert it ti an dynamic object
like
let newobject={MyFirstValue:"1",MySecondvalue:"2" }
The dynamic object here is that depending upon the numbers of values in the array the newobject should be able to transform
e.g.
if the array value changes =
array=[{"MyFirstValue":"1"},{MySecondvalue:"2"},{MyThirdValue:"2"}]
The newobject should transform to
newobject={MyFirstValue:"1",MySecondvalue:"2",MyThirdValue:"2" }
I tried using array.map and pushing the value but could not set the key property
It is like reducing the reducing the array to an object. I am not sure if i can use reduce.
You can accomplish this using Object.assign assuming your keys are unique.
const array = [{"key1":"1"}, {"key2":"2"}];
const newObject = Object.assign({}, ...array);
console.log(newObject);
You need to have unique keys in your object. Also, you should not expect all your objects to have 100% unique keys. Instead of having {key: 1, key: 2}, why not have the property key be an array of values; {key: [1, 2]}. I would use Array.prototype.reduce to achieve this.
const array = [{"key":"1", other: 'FOO'},{key:"2", dynamic: 'BAR', other: 'BAZ'}]
const object = array.reduce((initial, value) => {
Object.keys(value).forEach((key) => {
if(initial[key]) initial[key].push(value[key])
else initial[key] = [value[key]]
})
return initial;
}, {})
console.log(object)
try
let newobject= array.reduce((x,y)=> ({...x,...y}), {});
let array=[{"MyFirstValue":"1"},{MySecondvalue:"2"}]
let newobject= array.reduce((x,y)=> ({...x,...y}), {});
console.log(newobject);
Using ES5:
var input = [{"MyFirstValue":"1"},{MySecondvalue:"2"},{MyThirdValue:"2"}];
var output = Object.assign.apply({}, input);
console.log(output);

Remove reference to another object in javascript

var b = {};
var a = b;
b.test = 123;
console.log(a.test);
I am trying to write code similar to the above, however for sake of not having to describe context I'll display that instead ^
After the line a = b I want to lose the reference from a to b, so I can update b without it affecting a, and vice-versa
Is this possible?
You can clone your object with Object.assign():
var a = Object.assign({}, b);
You can use JSON.stringify(obj) and then JSON.parse to the string.
So it'll be something like that:
let obj= {
hello: 'hello'
};
let string = JSON.stringify(obj);
let newObj = JSON.parse(string);
Or a shorter, one-line way:
let newObj = JSON.parse(JSON.stringify(obj))
Using Object.assign(), Object.create() or spread operator will not help you with arrays in objects (works with non-array properties though).
let template = {
array: []
};
let copy = { ...template };
console.log(template.array); // As expected, results in: []
copy.array.push(123);
console.log(template.array); // Output: [123]
But this can be solved using JSON.stringify() and JSON.parse(), as already said.
let template = {
array: []
};
let copy = JSON.parse(JSON.stringify(template));
console.log(template.array); // Output: []
copy.array.push(123);
console.log(template.array); // Output: []
Wonder if it is the most adequate solution...
Excuses if I'm missing something, am only a beginner.

Why does a js map on an array modify the original array?

I'm quite confused by the behavior of map().
I have an array of objects like this:
const products = [{
...,
'productType' = 'premium',
...
}, ...]
And I'm passing this array to a function that should return the same array but with all product made free:
[{
...,
'productType' = 'free',
...
}, ...]
The function is:
const freeProduct = function(products){
return products.map(x => x.productType = "free")
}
Which returns the following array:
["free", "free", ...]
So I rewrote my function to be:
const freeProduct = function(products){
return products.map(x => {x.productType = "free"; return x})
}
Which returns the array as intended.
BUT ! And that's the moment where I loose my mind, in both cases my original products array is modified.
Documentation around map() says that it shouldn't ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map ).
I even tried to create a clone of my array turning my function into this:
const freeProduct = function(products){
p = products.splice()
return p.map(x => {x.productType = "free"; return x})
}
But I still get the same result (which starts to drive me crazy).
I would be very thankful to anyone who can explain me what I'm doing wrong!
Thank you.
You're not modifying your original array. You're modifying the objects in the array. If you want to avoid mutating the objects in your array, you can use Object.assign to create a new object with the original's properties plus any changes you need:
const freeProduct = function(products) {
return products.map(x => {
return Object.assign({}, x, {
productType: "free"
});
});
};
2018 Edit:
In most browsers you can now use the object spread syntax instead of Object.assign to accomplish this:
const freeProduct = function(products) {
return products.map(x => {
return {
...x,
productType: "free"
};
});
};
To elaborate on SimpleJ's answer - if you were to === the two arrays, you would find that they would not be equal (not same address in memory) confirming that the mapped array is in fact a new array. The issue is that you're returning a new array, that is full of references to the SAME objects in the original array (it's not returning new object literals, it's returning references to the same object). So you need to be creating new objects that are copies of the old objects - ie, w/ the Object.assign example given by SimpleJ.
Unfortunately, whether the spread operator nor the object assign operator does a deep copy.... You need to use a lodash like function to get areal copy not just a reference copy.
const util = require('util');
const print = (...val) => {
console.log(util.inspect(val, false, null, false /* enable colors */));
};
const _ = require('lodash');
const obj1 = {foo:{bar:[{foo:3}]}};
const obj2 = {foo:{bar:[{foo:3}]}};
const array = [obj1, obj2];
const objAssignCopy = x => { return Object.assign({}, x, {})};
const spreadCopy = x => { return {...x}};
const _Copy = x => _.cloneDeep(x);
const map1 = array.map(objAssignCopy);
const map2 = array.map(spreadCopy);
const map3 = array.map(_Copy);
print('map1', map1);
print('map2', map2);
print('map3', map3);
obj2.foo.bar[0].foo = "foobar";
print('map1 after manipulation of obj2', map1); // value changed
print('map2 after manipulation of obj2', map2); // value changed
print('map3 after manipulation of obj2', map3); // value hasn't changed!
Array Iterator Array.map() creates the new array with the same number of elements or does not change the original array. There might be the problem with referencing if there is object inside the array as it copies the same reference, so, when you are making any changes on the property of the object it will change the original value of the element which holds the same reference.
The solution would be to copy the object, well, array.Splice() and [...array](spread Operator) would not help in this case, you can use JavaScript Utility library like Loadash or just use below mention code:
const newList = JSON.parse(JSON.stringify(orinalArr))
Array Destructuring assignment can be used to clone the object.
const freeProduct = function(products){
p = products.splice()
return p.map(({...x}) => {x.productType = "free"; return x})
}
This method will not modify the original object.

Convert Object to 2D array in JavaScript

Can we convert an Object to a 2D Array,
My Object is like this
So That Array Key will be like 'STARS_2' and value is ["STARS_4", "STARS_0", "STARS_12"]
with My attempts I can get something like this,
With this Code,
var testArray =[];
_.map(childFieldNames, function (value, key) {
var newArray = new Array();
newArray[key] = value;
testArray.push(newArray);
});
Here Keys are actually another array, which I do not want. I want key should be like 'STARS_2' , i.e. property of master object.
Is this what you need?
var ary2D = Object.keys(childFieldNames).map(function (key) {
return childFieldNames[key];
});
better version for what Shilly showed would be:
const arr2D = Object.values(childFieldNames);
Object.entries(obj)
E.g.
const objVariable = {name: "Ted", job: "Dentist"}
const 2dArray = Object.entries(objVariable)
console.log(2dArray) // will print [["name", "Ted"], ["job", "Dentist"]]
Object.entries is a static method that belongs to the Object class. As a parameter, it accepts an object and returns a two-dimensional array.
Read more about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
You don’t need to create your structure into 2D array to just iterate over each key and its respective value(which is an array). If you want to iterate over it you can do something like this.
const object = {
a: [1,2,3],
b: [2,3,5]
};
for (const [key, value] of Object.entries(object)) {
value.forEach(v=>{
console.log(`${key}: ${v}`);
})
}

Categories

Resources