I'm trying to convert a json response code, but i keep getting a back a string array instead.
The header fields are depending on the table I query, so I cannot hardcode these.
I get a json response like:
{
"records": [
[
1,
"page one",
300
],
[
2,
"page 2",
500
]
],
"header: [
"page_id",
"page_name",
"total"
]
}
But i would like to convert this to
{
[
{
"page_id": 1,
"page_name": "page one",
"total": 300
},
{
"page_id": 2,
"page_name": "page 2",
"total": 500
}
]
}
I tried to create an Array and converting this to json but it still returns a string array, instead of a json array
let array = new Array;
records.forEach((record) => {
const parts = [];
let i = 0;
header.forEach((title) => {
const part = title + ': ' + record[i];
parts.push(part);
i++;
});
array.push(JSON.parse(JSON.stringify(parts)));
});
console.log(array) // Shows a string array?
I would expect
{
[
{
"page_id": 1,
"page_name": "page one",
"total": 300
},
{
"page_id": 2,
"page_name": "page 2",
"total": 500
}
]
}
But actual
[
[ 'page_id: 1', 'page_name: page 1', 'total: 300'],
[ 'page_id: 2', 'page_name: page 2', 'total: 500']
]
The issue with the way you are doing it, is you are creating an array and pushing the values onto it, where what you want to do is create the array and push objects onto it that contain your values...
This can be done with a small amount of code using map (documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
results.records.map((arr)=> ({
page_id: arr[0],
page_name: arr[1],
total: arr[2]
});
You can also deconstruct it like so
results.records.map(([page_id, page_name, total])=> ({
page_id,
page_name,
total,
});
/*jshint esversion: 6 */
let records = {
"records": [
[
1,
"page one",
300
],
[
2,
"page 2",
500
]
],
"header": [
"page_id",
"page_name",
"total"
]
};
let arr1 = records.header.map(data => data + ":");
let finalarray = new Array(10);
var keys = arr1;
var values = records.records;
finalarray = [];
values.forEach((data,index) =>{
var objJSON = new Object({});
for (i = 0; i < keys.length; i++) {
objJSON[keys[i]] = data[i];
}
finalarray.push(objJSON);
});
console.log(finalarray);
I have stored your given data in records object and then mapped the headers with colon ":" and in second loop I have joined both arrays in json object.
Output is now:
[ { 'page_id:': 1, 'page_name:': 'page one', 'total:': 300 },
{ 'page_id:': 2, 'page_name:': 'page 2', 'total:': 500 } ]
Related
How do I flatten a nested array?
[
{
"page": 1,
"items": [
{
"addresses": [
"hello1",
"hello2"
]
}
]
},
{
"page": 2,
"items": [
3,
{
"addresses": [
"hello3",
"hello4"
]
}
]
},
{
"page": 3,
"items": [
3,
4
]
}
];
Desired output ist:
["hello1", "hello2", "hello3", "hello4"]
import 'dart:convert';
main() {
const jsonString =
'[{"page":1, "items": [{"addresses": ["hello1","hello2"]}]}, {"page":2, "items": [3, {"addresses": ["hello3","hello4"]}]}, {"page":3, "items": [3, 4]}]';
final items = jsonDecode(jsonString) as List;
final x = items.expand((p) => p["items"]).expand((p) => p["addresses"]);
print(x);
}
Ok, so you have a list of maps that look like this:
{
page: int,
items: List<{
addresses: List<String>
}>
except sometimes the items are just numbers, you want to get all addresses on a single list, here is how I would do it:
List<String> result = [];
p.forEach((obj) {
final objMap = obj as Map<String, dynamic>
objMap['items'].forEach((item) {
if (item is Map<String, dynamic>) {
result.addAll(item['addresses'] as List<String>);
}
});
});
A bit clunky, I know, but I think it will do the trick
I have an jason result as below and I want to read from it and push to specific key as below
JSON result
[
{id:1,Name:"test",billNumber:"123"}
{id:2,Name:"test1",billNumber:"123"}
{id:3,Name:"test2",billNumber:"12345"}
{id:2,Name:"test3",billNumber:"12345"}
{id:3,Name:"test4",billNumber:"12334535"}
]
I want to have array list as below
{
"123":[{id:1,Name:"test",billNumber:"123"}, {id:2,Name:"test1",billNumber:"123"}],
"12345":[ {id:3,Name:"test2",billNumber:"12345"},{id:2,Name:"test3",billNumber:"12345"}],
"12334535":[{id:3,Name:"test4",billNumber:"12334535"}]
}
How to get the above list from the json result. Please do help
You don't need lodash to do that: just a regular Array.prototype.reduce will do the work. At each iteration, you simply check if the billNumber of the current item is in the object:
if it is not (i.e. a new entry), then you assign an array with a single element
if it is (i.e. the billNumber has been encountered before), then you simply push into the array
See proof-of-concept below:
const data = [{
id: 1,
Name: "test",
billNumber: "123"
}, {
id: 2,
Name: "test1",
billNumber: "123"
}, {
id: 3,
Name: "test2",
billNumber: "12345"
}, {
id: 2,
Name: "test3",
billNumber: "12345"
}, {
id: 3,
Name: "test4",
billNumber: "12334535"
}];
const transformedData = data.reduce((acc, cur) => {
if (cur.billNumber in acc) {
acc[cur.billNumber].push(cur);
} else {
acc[cur.billNumber] = [cur];
}
return acc;
}, {});
console.log(transformedData);
Use groupBy from lodash:
const result = groupBy(input, "billNumber")
(input is your array)
you can use reduce method.
[
{id:1,Name:"test",billNumber:"123"},
{id:2,Name:"test1",billNumber:"123"},
{id:3,Name:"test2",billNumber:"12345"},
{id:2,Name:"test3",billNumber:"12345"},
{id:3,Name:"test4",billNumber:"12334535"},
].reduce((acc, value) => {
if (!acc[value.billNumber]) {
acc[value.billNumber] = [];
}
acc[value.billNumber].push(value);
return acc;
}, {})
Here is the mimic code You cann use and get help
var a = [{a:2},{a:3},{a:4}]
let b = {}
let c = 1
a.forEach(obj => {
b[c] = [obj]
c++
})
output will be
{
1: [ { a: 2 } ],
2: [ { a: 3 } ],
3: [ { a: 4 } ]
}
Thanks I hope it will help !
I am implementing a Mat-Tree using Angular Material. I have a flat JSON string like:
"Entity": [
{
"ID": 1,
"NAME": "Reports",
"PARENTID": "0",
"ISACTIVE": "Y",
"CREATIONDATE": "2020-03-31T15:08:11",
"UPDATIONDATE": "2020-03-31T15:08:11",
"CREATEDBY": 596241,
"UPDATEDBY": 596241
},
{
"ID": 2,
"NAME": "TMS - Reports",
"PARENTID": 1,
"ISACTIVE": "Y",
"CREATIONDATE": "2020-03-31T15:08:38",
"UPDATIONDATE": "2020-03-31T15:08:38",
"CREATEDBY": 596241,
"UPDATEDBY": 596241
},
{
"ID": 3,
"NAME": "TMS - Beneficiary ",
"PARENTID": 2,
"ISACTIVE": "Y",
"CREATIONDATE": "2020-03-31T15:09:34",
"UPDATIONDATE": "2020-03-31T15:09:34",
"CREATEDBY": 596241,
"UPDATEDBY": 596241
}
]
And I need to convert it into Key-value pairs based on their Parent ID. Something like:
{
Reports:
{
'Type 1 Reports': ['Beneficiary Reports', 'Some Other Report'],
'Type 2 Reports': null //No Children,
},
Some Other Menu Items: {
'My Parent Node': null,
'Some Other Menu Node': ['Child 1', 'Child 2']
}
}
So far, I am able to use this code to convert it into a parent-child hierarchy, but It has pushed all children into Items array which I cannot iterate with Mat-Tree. I need to get rid of the Items and have something like a key-value pair as the one I mentioned above:
generateTreeData(menuResponse)
{
var map = {};
for(var i = 0; i < menuResponse.length; i++){
var obj = menuResponse[i];
var parent = '';
obj.items= [];
map[obj.ID] = obj;
if(obj.PARENTID == "0")
{
parent = '-';
}
else
{
parent = obj.PARENTID;
}
if(!map[parent]){
//Means Parent doesnt exist i.e. node Itself is parent node
map[parent] = {
items: []
};
}
map[parent].items.push(obj);
}
return map['-'].items;
}
Problem:
The code puts children nodes in Items array. I need to get rid of the Items array and place it in key-value pairs like the one I mentioned above. How do I just extract the "NAME" and Items out of this JSON array and make a Key-Value pair? Something like the one I mentioned above?
The expected output structure doesn't seem right. What if there is a child for 'Beneficiary Reports' node.
The output structure for the input provided in the question should be like:
{
"Reports":[
{
"TMS - Reports":[
{
"TMS - Beneficiary ":[]
}
]
}
]
}
Check the following fiddle: https://jsfiddle.net/abby_7700/apkgeo1d/3/
var data = [];//your response goes here
var result = {};
var root = data.find(x => x.PARENTID == 0);
result[root.NAME] = [];
findAndAddChildren(root.ID, result[root.NAME]);
console.log(JSON.stringify(result));
function findAndAddChildren(parentID, collection) {
var rootChildren = data.filter(x => x.PARENTID == parentID);
for(var i = 0; i < rootChildren.length; i++) {
var child = rootChildren[i];
var temp = {};
temp[child.NAME] = [];
collection.push(temp);
findAndAddChildren(child.ID, temp[child.NAME]);
}
}
I have an object that has an array of page objects and each page object has an array of questions.
Ex object:
{
Id: 1,
UserId: 14,
Deleted: false,
Collaborators: [],
Title: "Awesome",
Pages: [{
Id: 1,
Title: 'Jank',
Questions: [
{ Id: 1, Content: 'Ask me about it' },
{ Id: 2, Content: 'Ask me about it again' }
]
}, {
Id: 2,
Title: 'Janker',
Questions: [
{ Id: 1, Content: 'Tell me about it' },
{ Id: 2, Content: 'Tell me about it again' }
]
}]
}
What I am trying to do is to get a count of all the questions for the entire bas object. I am not sure how to do that. I have tried to use aggregate and $sum the total questions and then do another function to $sum those all together to get a total for the entire object. Unfortunately my $sum is not working like I thought it would.
Ex code (nodejs):
var getQuestionCount = function(id) {
var cursor = mongo.collection('surveys').aggregate([{
$match: {
$or: [{
"UserId": id
}, {
"Collaborators": {
$in: [id]
}
}]
}
}, {
$match: {
"Deleted": false
}
}, {
$unwind: "$Pages"
},
{ $group: { _id: null, number: { $sum: "$Pages.Questions" } } }
], function(err, result) {
//This log just gives me [object Object], [object Object]
console.log('q count ' + result);
});
}
Any idea how to do this? My end result from the example object above would ideally return 4 as the question count for the whole object.
I'd try following shell query.
db.collection.aggregate([
// filter out unwanted documents.
{$match:{Id: 1}},
// Unwind Pages collection to access Questions array
{$unwind:"$Pages"},
// Count items in Questions array
{$project:{count: {$size:"$Pages.Questions"}}},
// Finally sum items previously counted.
{$group:{_id:"$_id", total: {$sum: "$count"}}}
])
Based on your sample document, it should return correct count of Questions.
{
"_id" : ObjectId("57723bb8c10c41c41ff4897c"),
"total" : NumberInt(4)
}
I have a JSON config file as follows:
var conf = [
{
"value": "baz",
"threshold": 20,
"other": 123
},
{
"value": "mo",
"other": 456,
"child": {
"value": "foo",
"other": 789,
"child": {
"value": "larry",
"other": 123
}
}
}
];
I have a requirement to extract each of the objects and persist them together in order if they have child objects. For example, object 1 (baz) is stand alone. Object 2 (mo) will have two child objects. These 3 as a set must be extracted together.
There is no limit to the number of child objects.
Im attempting to persist each object using an array to maintain the order. So the required output would look like:
[[{"value":"baz","threshold":20,"other":123}],
[[{"value":"mo","other":456,"child":{"value":"foo","other":789,"child":{"value":"larry","other":123}}}],
[{"value":"foo","other":789,"child":{"value":"larry","other":123}}],
[{"value":"larry","other":123}]]]
A final requirement is to actually remove the child values from the parents so the output can actually be like:
[
[{"value":"baz","threshold":20,"other":123}],
[
[{"value":"mo","other":456}],
[{"value":"foo","other":789}],
[{"value":"larry","other":123}]
]
]
Ive been hung up on this for hours with little progress. I know I need to create a recursive function, push each node to an array, and then check for child object and repeat.
Heres what I have so far. My thinking is if I can take the array id each task is being pushed to (using a loop id), perhaps I can map that when the function is called again.
Appreciate any guidance.
var execSets = [];
function parser(tasks){
// an ordered array of task execution
for (let eachTask in tasks) {
var taskSet = [];
console.log("====================================");
console.log(tasks[eachTask]);
if(!tasks[eachTask].child && typeof(tasks[eachTask]) === 'object'){
console.log(tasks[eachTask]);
taskSet.push(tasks[eachTask]);
execSets.push(taskSet);
}
if(tasks[eachTask].child){
let childAlias = tasks[eachTask].child;
delete tasks[eachTask].child;
taskSet.push(tasks[eachTask]);
execSets.push(taskSet);
parser(childAlias);
}
}
}
The npm registry is your friend; try 'npm search flat,
There are a few modules that can help flatten a json object. For example https://www.npmjs.com/package/flat
You could do it using recursion. Here is my suggestion:
var conf = [
{
"value": "baz",
"threshold": 20,
"other": 123
},
{
"value": "mo",
"other": 456,
"child": {
"value": "foo",
"other": 789,
"child": {
"value": "larry",
"other": 123
}
}
}
];
function getFlattenedObject(object){
var response = [];
flatten(object, response, 0);
return response;
}
function flatten(object, array, index){
if(!array[index]){
array.push([]);
}
array[index].push(object);
if(object.child){
flatten(object.child, array, index + 1);
object.child = undefined;
}
}
//Logs for comparison
console.dir(conf)
console.dir(getFlattenedObject(conf));
The result structure you are looking for wasn't "intuitive" and hence the solution has gotten a little ugly, but here is how you could use object-scan to answer your question
// const objectScan = require('object-scan');
const data = [{"value":"baz","threshold":20,"other":123},{"value":"mo","other":456,"child":{"value":"foo","other":789,"child":{"value":"larry","other":123}}}]
const fn = (haystack) => objectScan(['[*]', '**.child'], {
filterFn: ({
key: [id, ...p],
value: { child, ...node },
context
}) => {
if (!(id in context)) {
context[id] = [];
}
context[id].push(child || p.length !== 0 ? [node] : node);
}
})(haystack, []);
console.log(fn(data));
// => [ [ { value: 'baz', threshold: 20, other: 123 } ], [ [ { value: 'larry', other: 123 } ], [ { value: 'foo', other: 789 } ], [ { value: 'mo', other: 456 } ] ] ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan#13.7.1"></script>
Disclaimer: I'm the author of object-scan