How to combine two JSON objects together [duplicate] - javascript

This question already has answers here:
How can I merge properties of two JavaScript objects dynamically?
(69 answers)
Closed 2 years ago.
I have two JavaScript obj like so:
const objOne = {
"firstname": "xzxz",
"lastname": "xzxzxzx"
};
const objTwo = {
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
};
and I want to combine them like below (not sure if "combine" is the appropriate word but hopefully make sense)
{
"firstname": "xzxz",
"lastname": "xzxzxzx",
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
}
so far I tried the below
let result = [];
results.push(objOne);
results.push(objTwo);
but surely the result is not the one I want and it make sense as I create an array and I push into both objects.
[
{
"firstname": "xzxz",
"lastname": "xzxzxzx"
},
{
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
}
]

const objOne = {
"firstname": "xzxz",
"lastname": "xzxzxzx"
};
const objTwo = {
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
};
const output = { ...objOne, ...objTwo };
console.log(output);

You could use Object.entries() to convert the objects into arrays and Object.fromEntries to convert it back into an object.
const objOne = {
"firstname": "xzxz",
"lastname": "xzxzxzx"
};
const objTwo = {
"title": [
{
"name": "foo",
"table": "First"
},
{
"name": "bar",
"table": "Second"
}
]
};
const combined = Object.fromEntries(
Object.entries(objOne)
.concat(Object.entries(objTwo))
);
console.log(combined);

Related

Iterate array of objects with string array [duplicate]

This question already has answers here:
Filter array of objects based on another array in javascript
(10 answers)
Closed 2 years ago.
I have an array of objects (JAVASCRIPT) like below
[
{
"code": "123",
"label": "Test123"
},
{
"code": "234",
"label": "Test"
},
{
"code": "980",
"label": "joe"
}
]
And i have a string array like below
["123", "234"]
I want to loop through array of objects and pass string array to get the "label"
I am expecting an output like below
[
{
"code": "123",
"label": "Test123"
},
{
"code": "234",
"label": "Test"
}
]
Please let me know if there is any efficient solution (JAVASCRIPT) because my array of objects is big.
Try this:
const obj = [
{
"code": "123",
"label": "Test123"
},
{
"code": "234",
"label": "Test"
},
{
"code": "980",
"label": "joe"
}
];
const arr = ["123", "234"];
var output = arr.flatMap(item => obj.filter(x => x.code == item));
console.log(output);
If the array is big, this can help to use Array.reduce.
const input = [{
"code": "123",
"label": "Test123"
},
{
"code": "234",
"label": "Test"
},
{
"code": "980",
"label": "joe"
}
]
const input2 = ["123", "234"];
const inputObj =input.reduce((acc, cur) => {
acc[cur.code] = cur.label;
return acc;
}, {});
const result = input2.reduce((acc, cur) => {
if (inputObj[cur]) {
acc.push({
code: cur,
label: inputObj[cur]
});
}
return acc;
}, []);
console.log(result);

How to dynamically push an array using spread operator Javascript

[
{
"details": {
"name": "john",
"point": "20"
},
"list": {
"number": "30",
}
},
{
"details": {
"name": "doe",
"point": "25"
},
"list": {
"number": "30",
}
}
]
This is what i am trying to do, i am getting the data from the store and if the response is only one i use data = getData[0].details and if the response is more than one then i push the data using [...data, ...getData[1].details] if there are more than one data how can i achieve. thanks in advance
let data:any = [];
this.store
.pipe(
select(getData),
map((getData,i) => {
if (getData) {
data = [...data, ...getData[i].details]
}
return data;
})
)
I think you want to get an array of the details.
In this case you can say.
let data = [
{
"details": {
"name": "john",
"point": "20"
},
"list": {
"number": "30",
}
},
{
"details": {
"name": "doe",
"point": "25"
},
"list": {
"number": "30",
}
}
];
let details = data.map(a => a.details);
console.log(details);
I think i understand what you mean:
What I would do is map over your getData response and add to the original array on each iteration. It wont matter if there is 1 or many in the getData array:
getData.map(x => $data.push(x.details));

Lodash to filter out an array of objects

I am trying to filter out a nested array of objects using lodash which is pretty straightforward but I am looking to avoid multiple calls.
I am looking to create 2 array of objects using a single lodash call/function. Looking to find object property "$isMultiAccount" if it exists put the whole object into one result set and if not put it to another ruleset.
Currently I am doing this with Lodash "has and filter" for first and for other "!has" which means same object is looped twice , as object is relatively large its creating bottleneck for speed
https://repl.it/repls/HomelyExpensiveTruetype
const item = {
"domains": [
{
"id": "dm11022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./Yes"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./No"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"conf": {
"isVpnBased":{
"accountType": "Primary"
}
}
}
]
}
}
}
]
}
/*
Expected result
output1 = [
{
"id": "dm11022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./Yes"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./No"
}
]
}
}
}
]
// $isMultiAccount account do not exist in this object
output2 = [
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"conf": {
"isVpnBased":{
"accountType": "Primary"
}
}
}
]
}
}
}
]
*/
const item = {
"domains": [
{
"id": "dm11022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./Yes"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"$isMultiAccount": "./No"
}
]
}
}
},
{
"id": "dm12022",
"information":{
"description": "Customer",
"owner": {
"primary":{
"name": "James",
"phone": "NA"
},
"others": [
{
"conf": {
"isVpnBased":{
"accountType": "Primary"
}
}
}
]
}
}
}
]
}
const [areMulti, areNotMulti] = _.reduce(item.domains, (current, next) => {
return _.has(next, ‘information.owner.others.$isMultiAccount’)
? [current[0].concat(next), current[1]]
: [current[0], current[1].concat(next)];
}, [[], []]);
console.log(areMulti);
console.log(areNotMulti);
Since item.domains.information.owner.others is an array, you need to tackle it as follows:
let multi = [];
let notMulti = [];
_.each(item.domains, function (obj) {
if (obj.information.owner.others.length && _.has(obj.information.owner.others[0], '$isMultiAccount'))
multi.push(obj);
else
notMulti.push(obj);
});
console.log(multi);
console.log(notMulti);
Unfortunately, you have to iterate over the domains array as well ass on the owner.others array to determine if the object with specific key sits inside.
So the algorithm has O(n*m) complexity.
If you ask for a lodash function seems that the partition method is what you're looking for
As docs says:
Creates an array of elements split into two groups, the first of which contains elements predicate returns truthy for, the second of which contains elements predicate returns falsey for. The predicate is invoked with one argument: (value).
So it will be like:
_.partition(
item.domains,
e => _.some(
_.get(e, 'information.owner.others'),
el => _.has(el,"$isMultiAccount")
)
);
Watch out - some hack available!
However, if the you're 100% sure that the element you're looking for will be always at specific index (for example it is supposed to be always as first element - so index 0) you can limit the algorithm to have linear complexity O(n) as only the size of the domains array will matter in terms of performance.
The hackish solution assuming fixed array index=0:
_.partition(
item.domains,
e => _.has(e, 'information.owner.others.0.$isMultiAccount')
);
NOTE
Using lodash makes code a bit easier to read but of course it creates some performance overhead anyway.

Building new JSON from existing one

I want to build an new JSON from existing one. The source has sections and rubrics that I no longer need for a listing. The new object called 'items' should have an array of the items.
The final JSON should be sorted by attribute 'name' and look like
{
"items": [
{
"id": 10000006,
"name": "Boah"
},
{
"id": 10000013,
"name": "Gut"
},
{
"id": 10000003,
"name": "Ipsum"
},
{
"id": 10000001,
"name": "Lorem"
},
{
"id": 10000005,
"name": "Lorum"
},
{
"id": 10000004,
"name": "Name"
},
{
"id": 10000002,
"name": "Stet"
}
]
}
For building the new JSON I get this source:
{
"sections": [
{
"name": "FooBar",
"rubrics": [
{
"name": "Foo",
"items": [
{
"id": 10000001,
"name": "Lorem"
},
{
"id": 10000002,
"name": "Stet"
},
{
"id": 10000003,
"name": "Ipsum"
}
]
},
{
"name": "Bar",
"items": [
{
"id": 10000004,
"name": "Name"
},
{
"id": 10000005,
"name": "Lorum"
},
{
"id": 10000006,
"name": "Boah"
}
]
}
]
},
{
"name": "BlahBloob",
"rubrics": [
{
"name": "Bla",
"items": [
{
"id": 10000013,
"name": "Gut"
}
]
},
{
"name": "Bloob",
"items": [
{
"id": 10000014,
"name": "Name"
},
{
"id": 10000015,
"name": "Lorem"
}
]
}
]
}
]
}
What do you think? How can I do this with plain JavaScript or maybe TypeScript?
Thanks for reading and have time for my question. And thanks for reply in advance.
Here you go. You just need to iterate over each rubric of each section of your source to get the items. At the end, sort your list of items by items, and you're done.
This example uses ES6 syntax, but it's easy to convert it to ES5 if needed.
function extractItems(source) {
const items = [];
for (const section of source.sections) {
for (const rubric of section.rubrics) {
items.push(...rubric.items);
}
}
items.sort((a, b) => a.name.localeCompare(b.name));
return { items };
}
A more functional approach use map and reduce to pick the rubrics and merge them.
data.sections
.map(section => section.rubrics) // get rubrics
.reduce((a, b) => a.concat(b)) // merge rubrics
.map(rubric => rubric.items) // get items from each rubric
.reduce((a, b) => a.concat(b)) // merge items
.sort((a, b) => a.name.localeCompare(b.name)); // sort
function(oldObj) {
var newObj = {
"items": []
};
oldObj.sections.forEach(function(section) {
section.rubrics.forEach(function(rubric) {
rubric.items.forEach(function(item) {
newObj.items.push(item);
});
});
});
newObj.items = newObj.items.sort(function(a, b) {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
});
return newObj;
}
And simply use JSON.parse() and JSON.stringify() to convert JSON to and from objects.
It might help you
var data ={
"sections": [
{
"name": "FooBar",
"rubrics": [{"name": "Foo", "items": [{"id": 10000001,"name": "Lorem"}, {"id": 10000002,"name": "Stet"}, {"id": 10000003,"name": "Ipsum"}]
}, {
"name": "Bar",
"items": [{
"id": 10000004,
"name": "Name"
}, {
"id": 10000005,
"name": "Lorum"
}, {
"id": 10000006,
"name": "Boah"
}]
}]
}, {
"name": "BlahBloob",
"rubrics": [{
"name": "Bla",
"items": [{
"id": 10000013,
"name": "Gut"
}]
}, {
"name": "Bloob",
"items": [{
"id": 10000014,
"name": "Name"
}, {
"id": 10000015,
"name": "Lorem"
}]
}]
}]
};
var itemObj = {};
var itemArr = [];
var sections = data.sections;
for(var i=0;i<sections.length;i++)
{
for(var j=0;j<sections[i].rubrics.length;j++){
for(var k=0;k<sections[i].rubrics[j].items.length;k++){
var itemObj;
itemObj['id'] = sections[i].rubrics[j].items[k].id;
itemObj['name'] = sections[i].rubrics[j].items[k].name;
itemArr.push(itemObj);
}
}
}
var finalObj = {"items":itemArr};
console.log(finalObj);
JSFiddle

split out object property and values from an array [duplicate]

This question already has answers here:
Remove a JSON attribute [duplicate]
(2 answers)
Closed 7 years ago.
From this json arrays
{
"result": [
{
"id": "1",
"name": "John",
"type": "B",
"score":"passed"
},
{
"id": "2",
"name": "Alice",
"type": "A",
"score":"failed"
}
]
}
How to split out some field and turn it intosomething like this
{
"result": [
{
"id": "1",
"type": "B",
},
{
"id": "2",
"type": "A",
}
]
}
I do not want to use splice in my case, above is just sample code.
Try this:
var input = {
"result": [
{
"id": "1",
"name": "John",
"type": "B",
"score":"passed"
},
{
"id": "2",
"name": "Alice",
"type": "A",
"score":"failed"
}
]
};
var output = {
result: input.result.map(function(item) {
return {
id: item.id,
type: item.type
};
})
}
Try like this
var json = {
"result": [{
"id": "1",
"name": "John",
"type": "B",
"score": "passed"
}, {
"id": "2",
"name": "Alice",
"type": "A",
"score": "failed"
}
]
};
json.result.forEach(function(item) {
delete item.name;
delete item.score;
});
console.log(json);
iterate over arry and remove age property
var json = [
{"name":"john",
"age":"30",
"gender":"male"},
{"name":"Alice",
"age":"20",
"gender":"female"}
];
json.forEach(function(x){
delete x['age'];
})

Categories

Resources