Push/Assign JSON child string to respective parent - javascript

I have a JSON string which is generated from an API.
[{"categories":{"category":{"id":"1","Name":"furit"}}},{"categories":{"category":{"id":"2","Name":"veg"}}},{"products":{"product":{"id":"1","Name":"fruit"}}},{"products":{"product":{"id":"2","Name":"pears"}}}]
how can I push all child values to their parent to look something like this.
[{"categories":{"category":[{"id":"1","name":"fruit"},{"id":"2","name":"veg"}]}},{"products":{"products":[{"id":"1","name":"apple"},{"id":"2","name":"pears"}]}}]
Thanks.
Updated data structure

You can create new object and use map to change your data structure and assign that data to new object.
var data = [{"categories":{"category":{"id":"1","Name":"furit"}}},{"categories":{"category":{"id":"2","Name":"veg"}}}]
var r = {
categories: {
category: data.map(o => o.categories.category)
}
}
console.log(r)
Updated For new data structure you can use forEach() loop and add to object.
var data = [{"categories":{"category":{"id":"1","Name":"furit"}}},{"categories":{"category":{"id":"2","Name":"veg"}}},{"products":{"product":{"id":"1","Name":"fruit"}}},{"products":{"product":{"id":"2","Name":"pears"}}}]
var r = {categories: {category: []}, products: {product: []}}
data.forEach(function(e) {
if(e.categories) r.categories.category.push(e.categories.category)
if(e.products) r.products.product.push(e.products.product)
})
console.log(r)

You can use Array.prototype.reduce() method, it will reduce all your array items category objects in a single categories array, giving the expected results
Your code should look like this:
var result = data.reduce(function(a, b) {
a[0].categories.push(b.categories);
return a;
}, [{
categories: []
}]);
Or if you want an object as result instead of an array use it like this:
var result = data.reduce(function(a, b) {
a.categories.push(b.categories);
return a;
}, {
categories: []
});
Demo:
var data = [{
"categories": {
"category": {
"id": "1",
"Name": "furit"
}
}
},
{
"categories": {
"category": {
"id": "2",
"Name": "veg"
}
}
}
];
var result = data.reduce(function(a, b) {
a[0].categories.push(b.categories);
return a;
}, [{
categories: []
}]);
console.log(result);
Edit:
This is an edit after adding products to your initial object:
var result = data.reduce(function(a, b) {
if(b.categories)
a[0].categories.push(b.categories);
if(b.products)
a[0].products.push(b.products);
return a;
}, [{
categories: [],
products : []
}]);
Demo:
var data = [{"categories":{"category":{"id":"1","Name":"furit"}}},{"categories":{"category":{"id":"2","Name":"veg"}}},{"products":{"product":{"id":"1","Name":"fruit"}}},{"products":{"product":{"id":"2","Name":"pears"}}}]
;
var result = data.reduce(function(a, b) {
if(b.categories)
a[0].categories.push(b.categories);
if(b.products)
a[0].products.push(b.products);
return a;
}, [{
categories: [],
products : []
}]);
console.log(result);

Related

Javascript: From JSON array of strings in the form of key:value to array of objects

say that I receive this JSON array from an API call.
[
"{'apple': 'enabled'}",
"{'banana': 'disabled'}"
]
How do I transform it into this:
[
{
label: 'apple',
value: 'enabled'
},
{
label: 'banana',
value: 'disabled'
}
]
The number of fields and the values are of course variable.
With JSON5.parse() I can transform it into this:
[
{
apple: 'enabled',
},
{
banana: 'disabled'
}
]
But this is still not what I need.
How can I achieve the transformation I need, without hacky workarounds that might change the values inside?
Thank you
const apiArray = [
"{'apple': 'enabled'}",
"{'banana': 'disabled'}"
];
const returnArray = [];
for (const element of apiArray) {
const parsedObj = JSON.parse(element);
const label = Object.keys(element)[0];
const value = parsedObj[label];
returnArray.push({"label": label, "value": value});
}
This inspects every element of the initial array on its own and extracts the label and the value. These then get pushed into the returnArray in the correct format.
I managed to make it work with this:
(Thanks #Alexander)
data.map(el=>{
const parsed = JSON5.parse(el)
return{
label: Object.keys(parsed)[0],
value: Object.values(parsed)[0]
}
})
However, it is not very clean.
you can try this
var newArr = [];
apiArray.forEach((element) => {
let obj = JSON.parse(element.replaceAll("'", '"'));
newArr.push({ label: Object.keys(obj)[0], value: Object.values(obj)[0] });
});
console.log(JSON.stringify(newArr));
you can try something like this :
myArray.map((data) => {
const parsedData = JSON.parse(data);
return {
label: Object.keys(parsedData).join(),
value: Object.values(parsedData).join(),
};
});
Output :
[{
"label": "apple",
"value": "enabled"
},
{
"label": "banana",
"value": "disabled"
}]

Create JSON Array dynamically from an object

I have an object A as shown below.
var A = {
"1": [ "1_1", "1_2", "1_3" ],
"2": [ "2_1", "2_2" ]
};
Need to build a new array dynamically using js. Suppose
object A key should map to attribute text of Array AA and value should be to children as given below.
var AA = [
{
"text": "1",
"state": "open",
"children": [
{ "text": "1_1" },
{ "text": "1_2" },
{ "text": "1_3" }
]
},
{
"text": "2",
"state": "open",
"children": [
{ "text": "2_1" },
{ "text": "2_2" }
]
}
];
This is my function but its not working as expected. Could someone pls help?
function constructJSONArr() {
var A = {
"1": [ "1_1", "1_2", "1_3" ],
"2": [ "2_1", "2_2" ]
};
for (var key in A) {
var tempArr = [];
tempArr.push(key);
for (var i = 0; i < key.length; i++) {
return {
'text': key,
'state': 'closed',
'children': A[key].map(function(child) {
return {
'text': child
};
})
}
}
}
}
When you return inside a function, the function ends and returns immediately. In your case, the return inside the for loop causes the function to return the 1st key object. To solve this, you need to create the objects and push them into an arr. You can return freely inside Array.map() because each iteration invokes a function.
Fixed solution:
Iterate with for...in. Get the key. Push a new object into arr. Use the key as the text property, the state, and children. To create the children get the array from the original object by the key, and use Array.map() to generate the child objects. Return arr.
var A = {
"1": ["1_1", "1_2", "1_3"],
"2": ["2_1", "2_2"]
};
function constructJSONArr(A) {
var arr = [];
for (var key in A) {
arr.push({
text: key,
state: 'closed',
children: A[key].map(function(t) {
return {
text: t
};
})
});
}
return arr;
}
var result = constructJSONArr(A);
console.log(result);
ESNext solution
Use Object.entries() to get keys and respective values from the object A. Iterate the entries with two nested Array.map() calls. The 1st to create the outer object, and the 2nd to create the children.
const A = {
"1": ["1_1", "1_2", "1_3"],
"2": ["2_1", "2_2"]
};
const constructJSONArr = (obj) =>
Object.entries(obj).map(([text, children]) => ({
text,
state: 'closed',
children: children.map((text) => ({
text
}))
}));
var result = constructJSONArr(A);
console.log(result);
You can use Object.keys() to iterate through the object and Array.map to create the new array.
var A = {
"1": ["1_1", "1_2", "1_3"],
"2": ["2_1", "2_2"]
};
var transformed = Object.keys(A).map(key => {
return {
text: key,
state: "open",
children: A[key].map(value => {
return {
text: value
};
})
};
});
console.log(transformed);

formatting dynamic json array

I have an json array as follows:
Maindata=[
{"name":"string1"},
{"name":"string2"},
{"name":"string3"}
];
what I need is an array of following type:
data=[
{
"name":"string1",
"name":"string2",
"name":"string3"
}
];
can anybody help me with some methods to obtain required json from original array.
(note: maindata is json array formed dynamically thats why its structure is like that)
Thanks in advance
You could use Object.assign and spread the array elements.
var array = [{ name1: "string1" }, { name2: "string2" }, { name3: "string3" }],
object = Object.assign({}, ...array);
console.log(object);
With reduce, you can do like following
var Maindata = [{
"name1": "string"
}, {
"name2": "string"
}, {
"name3": "string"
}];
var finalObj = Maindata.reduce((acc, cur) => {
Object.assign(acc, cur);
return acc;
}, {})
console.log(finalObj);
You can use Array.forEach or Array.reduce to iterate though the items of the Maindata object and for each item you can iterate through its keys(using Object.keys) and group the data into a new structure.(See the below snippet)
Solution using Array.forEach
var Maindata=[
{"name1":"string1"},
{"name2":"string2"},
{"name3":"string3"}
];
var result = {};
var newMaindata=[];
Maindata.forEach(function(el){
Object.keys(el).forEach(function(key){
result[key]=el[key];
});
});
newMaindata.push(result);
console.log(newMaindata);
Solution using Array.reduce
var Maindata = [{
"name1": "string1"
}, {
"name2": "string2"
}, {
"name3": "string3"
}];
var result ;
var newMaindata = [];
result = Maindata.reduce(function(acc,el) {
Object.keys(el).forEach(function(key) {
acc[key] = el[key];
});
return acc;
},{});
newMaindata.push(result);
console.log(newMaindata);

Javascript: Filter out on an array of objects and pick based on key, not value

Im trying to loop through an array of objects, which have different keys. Is there a way that I can pick an object based on they key?
var array = [
{
"1400": "Accident and Health"
},
{
"100": "Life"
},
{
"1300": "Pension"
}
]
var a = "100";
var pop = _.pick(array,a);
console.log(pop);
Desired output:
Life
Thank you!
You could use the in operator.
var array = [{ 1400: "Accident and Health" }, { 100: "Life" }, { 1300: "Pension" }];
var result = (key => array.find(item => key in item)[key])(100);
console.log(result);
var array = [
{
"1400": "Accident and Health"
},
{
"100": "Life"
},
{
"1300": "Pension"
}
]
var a = "100";
var pop = _.map(array, function(currentObject) {
var b= _.pick(currentObject, a);
if(!_.isEmpty(b))
console.log(b);
});
<script src="http://underscorejs.org/underscore-min.js"></script>
Lodash 4.17.2
_.chain(array).map('100').compact().head().value();

Get parent array key in deep nested object using lodash

I'm using Lodash JavaScript library in my project and have a problem in getting the parent array key object filtered object:
I've the following data:
var data = {
5: [{
id: "3",
label: "Manish"
}, {
id: "6",
label: "Rahul"
}, {
id: "7",
label: "Vikash"
}],
8: [{
id: "16",
label: "Pankaj"
}, {
id: "45",
label: "Akash"
}],
9: [{
id: "15",
label: "Sunil"
}]
}
My requirement is if I've the array of [6,16] then I want a new result array containing values 5,8 because these two array keys have objects which contain id:"6" and id:"16"
I tried it using _.flatten and _.pick method but could not work. I used the following code;
var list = [];
_.each(data, function(item){
list.push(_.omit(item, 'id'));
list.push(_.flatten(_.pick(item, 'id')));
});
var result = _.flatten(list);
console.log(result);
var res = _([6, 16]).map(function(id){
return _.findKey(data, function(arr){
return _.some(arr, {id: new String(id)});
})
}).compact().uniq().value();
If simple javascript solution is okay with you then
var searchId=[6,16];
var newArr = [];
for ( key in data ){
data[key].forEach( function(innerValue){
if ( searchId.indexOf( Number(innerValue.id) ) != -1 ) newArr.push( key );
} );
}
console.log(newArr);
try this:
( hope im not missing some syntax )
var result = [];
var filterArray = [6,16];
_.each(filterArray, function(item){
_.merge(result,_.filter(data, function(o) { return _.contains(o,{id:item}) }));
});
Using _.pickBy this problem is solved simply:
var myArr = [6, 16]
var res = _.pickBy(data, function (value) {
return _(value).map('id').map(_.toNumber).intersection(myArr).size();
});
console.log(res)
https://jsfiddle.net/7s4s7h3w/

Categories