Related
const array = [
{
"data": {
"qty": "5",
"toy": {
"id": 3,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 10,
},
"available": "no"
}
},
{
"data": {
"qty": "59",
"toy": {
"id": 10,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 3,
},
"available": "yes",
}
}
]
var result = [];
array.reduce(function(res, value) {
if (!res['data']['toy'] || !res['data']['toy']['data']) {
res['data'] = {...value['data'] };
result.push(res['data'])
}
if (res['data']['available'] === value['data']['available'] && res['data']['toy']['id'] === value['data']['toy']['id']) {
res['data']['qty'] = parseInt(res['data']['qty']) + parseInt(value['data'].qty)
}
return res;
}, {'data': {}});
console.log(result)
I am working on a js project and I need a bit of help here. From the array, How to get a new array that has qty as the sum of the other qty value which data.toy.id and available same. i.e. I want the below array. My code is not working as excepted. Changes to the same or new code are also fine. Thank you.
const array = [
{
"data": {
"qty": "10",
"toy": {
"id": 3,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 10,
},
"available": "no"
}
},
{
"data": {
"qty": "59",
"toy": {
"id": 10,
},
"available": "yes",
}
}
]
You group the array into an object, where the keys are concatenation of available and id properties and finally transform the object back to an array using Object.values.
const
array = [
{ data: { qty: "5", toy: { id: 3 }, available: "yes" } },
{ data: { qty: "5", toy: { id: 10 }, available: "no" } },
{ data: { qty: "59", toy: { id: 10 }, available: "yes" } },
{ data: { qty: "5", toy: { id: 3 }, available: "yes" } },
],
result = Object.values(
array.reduce((r, { data }) => {
const k = data.available + data.toy.id;
if (r[k]) {
r[k].data.qty = String(Number(r[k].data.qty) + Number(data.qty));
} else {
r[k] = { data };
}
return r;
}, {})
);
console.log(result);
I'd suggest using Array.reduce() to group by a key, which will be combined value of the toy id and the available property.
We'd create a map of all toys based on this key, summing the quantity for each.
Finally, we'll use Object.values() to convert back into an array.
const array = [ { "data": { "qty": "5", "toy": { "id": 3, }, "available": "yes", } }, { "data": { "qty": "5", "toy": { "id": 10, }, "available": "no" } }, { "data": { "qty": "59", "toy": { "id": 10, }, "available": "yes", } }, { "data": { "qty": "5", "toy": { "id": 3, }, "available": "yes", } } ];
const result = Object.values(array.reduce((acc, { data: { qty, toy, available } }) => {
const key = `${toy.id}-${available}`;
acc[key] = acc[key] || { data: { qty: 0, toy, available } };
acc[key].data.qty += Number(qty);
return acc;
}, {}))
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
You can use Array#reduce() to create arrayHash object using as keys: ${c.data.toy.id}-${c.data.available}
Code:
const array = [{data: {qty: '5',toy: {id: 3,},available: 'yes',},},{data: {qty: '5',toy: {id: 10,},available: 'no',},},{data: {qty: '59',toy: {id: 10,},available: 'yes',},},{data: {qty: '5',toy: {id: 3,},available: 'yes',},},]
const arrayHash = array.reduce((a, { data }) => {
const key = `${data.toy.id}-${data.available}`
a[key] = a[key] || { data: { ...data, qty: 0 } }
a[key].data.qty = (+a[key].data.qty + +data.qty).toString();
return a
}, {})
const result = Object.values(arrayHash)
console.log(result)
I'd use just reduce
const a1 = [
{
"data": {
"qty": "5",
"toy": {
"id": 3,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 10,
},
"available": "no"
}
},
{
"data": {
"qty": "59",
"toy": {
"id": 10,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 3,
},
"available": "yes",
}
}
]
const a2 = a1.reduce((acc, it) => {
let found = acc.find(
dp => dp.data.toy.id === it.data.toy.id && dp.data.available === it.data.available
)
if(found){
found.data.qty = ( Number(found.data.qty) + Number(it.data.qty) ).toString()
}
else acc.push(it)
return acc
}, [])
console.log(JSON.stringify(a2, null,2))
I am trying to write a for or JQuery. Each loop so that It will generate a new JSON Object from an array in a desired format. I want to output a JSON Object from an input JavaScript Array. I have a following input array to convert:
INPUT:
[
{
"parent": "parent_1",
"child": "abc",
"data": "data1"
},
{
"parent": "parent_1",
"child": "def",
"data": "data2"
},
{
"parent": "parent_1",
"child": "ghi",
"data": "data3"
},
{
"parent": "parent_2",
"child": "jkl",
"data": "data4"
},
{
"parent": "parent_2",
"child": "acc",
"data": "data5"
},
{
"parent": "parent_3",
"child": "mjh",
"data": "data6"
},
{
"parent": "parent_3",
"child": "fg1",
"data": "data7"
},
{
"parent": "parent_2",
"child": "dfg",
"data": "data8"
},
{
"parent": "parent_3",
"child": "jkk",
"data": "data9"
},
{
"parent": "parent_4",
"child": "3ff",
"data": "data10"
},
{
"parent": "parent_3",
"child": "mhg",
"data": "data11"
},
{
"parent": "parent_1",
"child": "gnh",
"data": "data12"
}
]
so from above array want to run a for or JQuery. Each loop so that it will generate a new JSON Object in the following format:
OUTPUT:
[
{
"parent_1": {
"child": [
{
"name": "abc",
"data": "data1"
},
{
"name": "def",
"data": "data2"
},
{
"name": "gh1",
"data": "data3"
},
{
"name": "gnh",
"data": "data12"
}
]
}
},
{
"parent_2": {
"child": [
{
"name": "jkl",
"data": "data4"
},
{
"name": "acc",
"data": "data5"
},
{
"name": "dfg",
"data": "data8"
}
]
}
},
{
"parent_3": {
"child": [
{
"name": "mjh",
"data": "data6"
},
{
"name": "fg1",
"data": "data7"
},
{
"name": "jkk",
"data": "data9"
},
{
"name": "mhg",
"data": "data11"
}
]
}
},
{
"parent_4": {
"child": [
{
"name": "3ff",
"data": "data10"
}
]
}
}
]
You could group the data by using parent as key for an object and add the rest of the object to the children array of the group.
This approach does not muate the given data.
const
data = [{ parent: "parent_1", child: "abc", data: "data1" }, { parent: "parent_1", child: "def", data: "data2" }, { parent: "parent_1", child: "ghi", data: "data3" }, { parent: "parent_2", child: "jkl", data: "data4" }, { parent: "parent_2", child: "acc", data: "data5" }, { parent: "parent_3", child: "mjh", data: "data6" }, { parent: "parent_3", child: "fg1", data: "data7" }, { parent: "parent_2", child: "dfg", data: "data8" }, { parent: "parent_3", child: "jkk", data: "data9" }, { parent: "parent_4", child: "3ff", data: "data10" }, { parent: "parent_3", child: "mhg", data: "data11" }, { parent: "parent_1", child: "gnh", data: "data12" }],
result = Object.values(data.reduce((r, { parent, ...o }) => {
r[parent] ??= { [parent]: { children: [] } };
r[parent][parent].children.push(o);
return r;
}, []));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I think you want something like this
const convertArray = (arr, field) => {
const obj = {};
arr.forEach(elem => {
const param = elem[field];
if (!Array.isArray(obj[param])) obj[param] = [];
delete elem[field];
obj[param].push(elem);
});
return Object.keys(obj).map(elem => {
return { [elem]: { child: obj[elem] } };
});
}
then you would use as
convertArray(*array*, "parent")
You can use .reduce function, for example:
var array = [ {name: 'item 1', cate: 'cate-1'}, {name: 'item 2', cate: 'cate-2'} ]
var object = array.reduce(function(obj, item) {
if (!obj[item.cate]) obj[item.cate] = {child: []};
obj[item.cate].child.push(item);
return obj;
}, {})
console.log(object);
You can use the below code for this.
var arr = [{"parent":"parent_1","child":"abc","data":"data1"},{"parent":"parent_1","child":"def","data":"data2"},{"parent":"parent_1","child":"ghi","data":"data3"},{"parent":"parent_2","child":"jkl","data":"data4"},{"parent":"parent_2","child":"acc","data":"data5"},{"parent":"parent_3","child":"mjh","data":"data6"},{"parent":"parent_3","child":"fg1","data":"data7"},{"parent":"parent_2","child":"dfg","data":"data8"},{"parent":"parent_3","child":"jkk","data":"data9"},{"parent":"parent_4","child":"3ff","data":"data10"},{"parent":"parent_3","child":"mhg","data":"data11"},{"parent":"parent_1","child":"gnh","data":"data12"}];
var result = {};
$.each(arr, function (i, item) {
if(!result[item.parent]) {
result[item.parent] = [];
}
var data = {'child': {'name': item.child, 'data': item.data}};
(result[item.parent]).push(data);
});
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I am having a dynamic JSON array in below format,
let main_data = [
{
"client":[
{
"name":"aaaa",
"count":"1",
"filter":{
"type":{
"name":"test3"
}
}
},
{
"name":"bbbb",
"count":"9",
"filter":{
"type":{
"name":"test2"
}
}
}
]
},
{
"compute":[
{
"name":"cccc",
"count":"6",
"filter":{
"type":{
"name":"test"
}
}
}
]
}
]
Here key "name" is unique. When updating a form, I will get an json array like below,
let new_data = [
{
"client":[
{
"name":"bbbb",
"count":"1234",
"type":{
"name":"updated_name"
}
}
}
]
}
]
I need to check the "name" in the json array in "main_data" and remove the existing one and update with the new "updated_data" into the "main_data". (no Jquery please)
Expected output,
let main_data = [
{
"client":[
{
"name":"aaaa",
"count":"1",
"filter":{
"type":{
"name":"test3"
}
}
},
{
"name":"bbbb",
"count":"123",
"filter":{
"type":{
"name":"updated_name"
}
}
}
]
},
{
"compute":[
{
"name":"cccc",
"count":"6",
"filter":{
"type":{
"name":"test"
}
}
}
]
}
]
Is there any way to achive this. Any help would be much appreciated. Thanks in advance.
Try this
let main_data = [{
client: [{
name: "aaaa",
count: "1",
filter: {
type: {
name: "test3"
}
}
},
{
name: "bbbb",
count: "9",
filter: {
type: {
name: "test2"
}
}
}
]
},
{
compute: [{
name: "cccc",
count: "6",
filter: {
type: {
name: "test"
}
}
}]
}
];
let new_data = [{
client: [{
name: "bbbb",
count: "1234",
filter: {
type: {
name: "updated_name"
}
}
}]
}];
const res = main_data.map((item, index) => {
if (item.client) {
const clients = item.client.map(client => {
if (client.name === new_data[0].client[0].name) {
client = new_data[0].client[0];
}
return client;
});
return {
client: clients
};
}
return item;
});
console.log(res);
There may very well be a fancy way to get this done but one can always just find the matching item and replace it. eg.
let main_data = [
{
"client": [
{
"name": "aaaa",
"count": "1",
"filter": {
"type": {
"name": "test3"
}
}
},
{
"name": "bbbb",
"count": "123",
"filter": {
"type": {
"name": "updated_name"
}
}
}
]
},
{
"compute": [
{
"name": "cccc",
"count": "6",
"filter": {
"type": {
"name": "test"
}
}
}
]
}
];
let new_data = [
{
"client": [
{
"name": "bbbb",
"count": "1234",
"type": {
"name": "updated_name"
}
}
]
}
];
console.log("before:" + JSON.stringify(main_data));
newItem = new_data[0]["client"][0];
mainDataList = main_data[0]["client"];
for (i = 0; i < mainDataList.length; i++) {
if (mainDataList[i].name == newItem.name) {
mainDataList[i] = newItem;
}
}
console.log("after:" + JSON.stringify(main_data));
will output
before:[{"client":[{"name":"aaaa","count":"1","filter":{"type":{"name":"test3"}}},{"name":"bbbb","count":"123","filter":{"type":{"name":"updated_name"}}}]},{"compute":[{"name":"cccc","count":"6","filter":{"type":{"name":"test"}}}]}]
after:[{"client":[{"name":"aaaa","count":"1","filter":{"type":{"name":"test3"}}},{"name":"bbbb","count":"1234","type":{"name":"updated_name"}}]},{"compute":[{"name":"cccc","count":"6","filter":{"type":{"name":"test"}}}]}]
Here's a simple way to do this, let's say your new data is at variable newData:
main_data.client.filter(item => item.name === newData.name).push(newData)
I have an existing params object as following
{
"application_context": {
"application_id": "a0",
"context_id": "c0"
},
"device_data": {
"device_id": "",
"hostname": ""
},
"query_options": {
"page_token": "",
"page_size": 30
}
}
My desired object should be following
{
"application_context": {
"application_id": "a0",
"context_id": "c0"
},
"device_data": {
"device_id": "",
"hostname": ""
},
"query_options": {
"page_token": "",
"page_size": 30,
"filter_list": [{
"operator": "OPERATOR_AND",
"field_list": [{
"field": "State",
"value": "INACTIVE_STATE"
}]
}]
}
}
I have created the following
param['filter_list'] = [{
'operator': 'OPERATOR_AND',
'field_list': filter
}];
where it's adding the following part with some logic
"field": "State",
"value": "INACTIVE_STATE"
But not able to add the above to get my complete object
You need to create filter_list on query_options key
let data = {
"application_context": {
"application_id": "a0",
"context_id": "c0"
},
"device_data": {
"device_id": "",
"hostname": ""
},
"query_options": {
"page_token": "",
"page_size": 30
}
}
data.query_options.filter_list = [{
"operator": "OPERATOR_AND",
"field_list": [{
"field": "State",
"value": "INACTIVE_STATE"
}]
}];
console.log(data)
You can add your data as:
obj["query_options"]["filter_list"] = param["filter_list"];
var obj = {
"application_context": {
"application_id": "a0",
"context_id": "c0"
},
"device_data": {
"device_id": "",
"hostname": ""
},
"query_options": {
"page_token": "",
"page_size": 30
}
};
var filter = [{
"field": "State",
"value": "INACTIVE_STATE"
}];
/*param['filter_list'] = */
var filter_list = [{
"operator": "OPERATOR_AND",
"field_list": filter
}]
obj["query_options"]["filter_list"] = filter_list ;
console.log(obj);
I have below an array
{
"sec": "11",
"details": [
{
"id": "1",
"user": "Me1"
},
{
"id": "2",
"uesr": "Me2"
},
{
"id": "3",
"user": "Me3"
}
{
"id": "4",
"user": "Me4",
parentID:"2"
},
{
"id": "5",
"uesr": "Me5"
},
{
"id": "6",
"user": "Me6",
parentID:"2"
}
{
"id": "7",
"user": "Me7"
},
{
"id": "8",
"uesr": "Me8",
parentID:"7"
},
{
"id": "9",
"user": "Me9",
parentID:"7"
}
],
"isDisplay": "true"
}
and output should be like below
{
"sec":"11",
"details":[
{
"id":"1",
"user":"Me1"
},
{
"id":"2",
"uesr":"Me2",
"childs":[
{
"id":"4",
"user":"Me4",
"parentID":"2"
},
{
"id":"6",
"user":"Me6",
"parentID":"2"
}
]
},
{
"id":"3",
"user":"Me3"
},
{
"id":"5",
"uesr":"Me5"
},
{
"id":"7",
"user":"Me7",
"childs":[
{
"id":"8",
"uesr":"Me8",
"parentID":"7"
},
{
"id":"9",
"user":"Me9",
"parentID":"7"
}
]
}
],
"isDisplay":"true"
}
I can do this by simple looping,
In lodash or anything angular does this functionality.
I am clueless to start,
I just give below code
this.list = _.groupBy(this.list,"parentID");
But the output not as expected.
Please help or guide
Thanks
You need a different approach, not grouping, but creating a tree out of the related data.
This solution uses an array with id as key and with parentID as well. The code works with a single loop, because of storing of the relation of children and parent and parent to their children.
How it works:
Basically for every object in the array it takes as well the id for building a new object as the parentID for a new object.
So for example this object
{ id: "6", parentID: "2", user: "Me6" }
it generates in o first with id this property
6: {
id: "6",
parentID: "2",
user: "Me6"
}
and then this property with parentID
2: {
children: [
{
id: "6",
parentID: "2",
user: "Me6"
}
]
},
and while all object treated like this, we finally get a tree.
At the end, the children array of the root property is returned.
function getTree(data, root) {
var o = {};
data.forEach(function (a) {
if (o[a.id] && o[a.id].children) {
a.children = o[a.id].children;
}
o[a.id] = a;
o[a.parentID] = o[a.parentID] || {};
o[a.parentID].children = o[a.parentID].children || [];
o[a.parentID].children.push(a);
});
return o[root].children;
}
var data = { sec: "11", details: [{ id: "1", user: "Me1" }, { id: "2", uesr: "Me2" }, { id: "3", user: "Me3" }, { id: "4", user: "Me4", parentID: "2" }, { id: "5", uesr: "Me5" }, { id: "6", user: "Me6", parentID: "2" }, { id: "7", user: "Me7" }, { id: "8", user: "Me8", parentID: "7" }, { id: "9", user: "Me9", parentID: "7" }], isDisplay: "true" },
result = { sec: "11", details: getTree(data.details, undefined), isDisplay: "true" };
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }