I have a batch of JSON files
looking like this :
{
"properties": [
{
"Frame": "Yellow"
},
{
"Sky": "Apocalypse"
},
{
"Grass": "green"
},
{
"Sign": "sign"
},
{
"Graffitis": "shit"
},
{
"Things": "can"
},
{
"Quotes": "emptyness"
},
{
"Border": "framing"
},
{
"Logo": "logo"
},
{
"Overlay": "overlay"
}
]
}
And I want to modify them so they look like this :
{
Border: "framing",
Frame: "Yellow",
Graffitis: "shit",
Grass: "green",
Logo: "logo",
Overlay: "overlay",
Quotes: "emptyness",
Sign: "sign",
Sky: "Apocalypse",
Things: "can"
}
How can I achieve this?
Use Object.assign like so
const input = {
"properties": [
{
"Frame": "Yellow"
},
{
"Sky": "Apocalypse"
},
{
"Grass": "green"
},
{
"Sign": "sign"
},
{
"Graffitis": "shit"
},
{
"Things": "can"
},
{
"Quotes": "emptyness"
},
{
"Border": "framing"
},
{
"Logo": "logo"
},
{
"Overlay": "overlay"
}
]
}
const output = Object.assign({}, ...input.properties);
You can use Array.prototype.reduce() and spread syntax to accomplish this in one line:
let obj = {
"properties": [{
"Frame": "Yellow"
}, {
"Sky": "Apocalypse"
}, {
"Grass": "green"
}, {
"Sign": "sign"
}, {
"Graffitis": "shit"
}, {
"Things": "can"
}, {
"Quotes": "emptyness"
}, {
"Border": "framing"
}, {
"Logo": "logo"
}, {
"Overlay": "overlay"
}]
}
console.log(obj["properties"].reduce((prev, current) =>
({ ...prev,
...current
}), {}))
Hey and welcome to StackOverflow!
I recommend using a for-loop to iterate through an object you have parsed from the json (JS read json file and use as an object):
let newObject = {};
properties.forEach(property => {
Object.assign(newObject, property);
}
return newObject;
Related
I'm trying to get the output of getQueryResults using the below code:
var AWS = require('aws-sdk');
var athena = new AWS.Athena();
const DEBUG = process.env.DEBUG;
const GLOCA_ENVID = process.env.GLOCA_ENVID;
const GLOCA_AWS_ACCOUNTID = process.env.GLOCA_AWS_ACCOUNTID;
const GLOCA_AWS_REGION = process.env.GLOCA_AWS_REGION;
exports.handler = function(event, context, callback) {
athena.getQueryResults({
QueryExecutionId: "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
},function(err,data){
if (err) console.log(err);
else {
console.log("Body: ", data);
}
});
}
Below is the output:
{
UpdateCount: 0,
ResultSet: { Rows: [ [Object] ], ResultSetMetadata: { ColumnInfo: [Array] } }
}
The output should look something like this:
{
"ResultSet": {
"Rows": [
{
"Data": [
{
"VarCharValue": "date"
},
{
"VarCharValue": "location"
},
{
"VarCharValue": "browser"
},
{
"VarCharValue": "uri"
},
{
"VarCharValue": "status"
}
]
},
{
"Data": [
{
"VarCharValue": "2014-07-05"
},
{
"VarCharValue": "SFO4"
},
{
"VarCharValue": "Safari"
},
{
"VarCharValue": "/test-image-2.jpeg"
},
{
"VarCharValue": "200"
}
]
},
{
"Data": [
{
"VarCharValue": "2014-07-05"
},
{
"VarCharValue": "SFO4"
},
{
"VarCharValue": "IE"
},
{
"VarCharValue": "/test-image-2.jpeg"
},
{
"VarCharValue": "200"
}
]
}
],
"ResultSetMetadata": {
"ColumnInfo": [
{
"CatalogName": "hive",
"SchemaName": "",
"TableName": "",
"Name": "date",
"Label": "date",
"Type": "date",
"Precision": 0,
"Scale": 0,
"Nullable": "UNKNOWN",
"CaseSensitive": false
},
{
"CatalogName": "hive",
"SchemaName": "",
"TableName": "",
"Name": "location",
"Label": "location",
"Type": "varchar",
"Precision": 2147483647,
"Data": [
"Scale": 0,
"Nullable": "UNKNOWN",
"CaseSensitive": true
},
{
"CatalogName": "hive",
"SchemaName": "",
"TableName": "",
"Name": "browser",
"Label": "browser",
"Type": "varchar",
"Precision": 2147483647,
"Scale": 0,
"Nullable": "UNKNOWN",
"CaseSensitive": true
}
]
}
},
"UpdateCount": 0
}
The above output is an example output, but a similar outcome is what I'm expecting. When I run in AWS CLI:
aws athena --region "us-west-2" get-query-results --query-execution-id a1b2c3d4-5678-90ab-cdef-EXAMPLE11111
I get the expected output, so I'm unable to understand why I can't get the same result via lambda.
Thank you so much for all the help! :)
It actually looks like the code is fine. Looking at the response is shows that there is an Object within the ResultSet.Rows. Try to stringify the result before logging such that the handler looks like this:
exports.handler = function(event, context, callback) {
athena.getQueryResults({
QueryExecutionId: "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
},function(err,data){
if (err) console.log(err);
else {
console.log("Body: ", JSON.stringify(data, null, 2));
}
});
}
Give the title:
row.push({"ticker" : PX_Hist[j]['ticker']});
Calcluate data with different timeframe parameters
const timeframes = [5,10,90,120,250,500];
for (let t = 0; t <= timeframes.length - 1; t++){
row.push({"move" : ((PX_Hist[j]['px'][PX_Hist[j]['px'].length-1]["adjusted_close"] / PX_Hist[j]['px'][PX_Hist[j]['px'].length-timeframes[t]]["adjusted_close"] -1))});
}
I am creating the following output with this code.
[
[
{
"ticker": "JPM"
},
{ "move": 0.01405944118170499 },
{ "move": 0.0337445573294628 },
{ "move": 0.1692882281117576 },
{ "move": 0.07636499188035195 },
{ "move": 0.8151371865267423 },
{ "move": 0.4537049320855997 }
],
[
{
"ticker": "C"
},
{ "move": -0.01295986622073586 },
{ "move": 0.002689694224235595 },
{ "move": 0.05544868117343582 },
{ "move": -0.0457495911125243 },
{ "move": 0.7837535634777528 },
{ "move": 0.05665004788714745 }
],
[
{
"ticker": "C"
},
{ "move": -0.01295986622073586 },
{ "move": 0.002689694224235595 },
{ "move": 0.05544868117343582 },
{ "move": -0.0457495911125243 },
{ "move": 0.7837535634777528 },
{ "move": 0.05665004788714745 }
],
]
I need to transpose the above array to something that I can easily bind to a table like below:
[{"ticker": "JPM", "5": 0.01405944118170499,"10": 0.0337445573294628,"90":
0.1692882281117576,"120": 0.07636499188035195,"250": 0.8151371865267423,"500":
0.4537049320855997}]
Any words of advice about how to do this in an elegant way?
You can so something like this, using map and for loop. But honestly I find this unnecessary. You could just do this from the get go in your loop. instead of pushing to row, you could try:
row[0][timeframes[t]] = "that long thing you have there"
const arr = [
[{
"ticker": "JPM"
},
{
"move": 0.01405944118170499
},
{
"move": 0.0337445573294628
},
{
"move": 0.1692882281117576
},
{
"move": 0.07636499188035195
},
{
"move": 0.8151371865267423
},
{
"move": 0.4537049320855997
}
],
[{
"ticker": "C"
},
{
"move": -0.01295986622073586
},
{
"move": 0.002689694224235595
},
{
"move": 0.05544868117343582
},
{
"move": -0.0457495911125243
},
{
"move": 0.7837535634777528
},
{
"move": 0.05665004788714745
}
],
[{
"ticker": "C"
},
{
"move": -0.01295986622073586
},
{
"move": 0.002689694224235595
},
{
"move": 0.05544868117343582
},
{
"move": -0.0457495911125243
},
{
"move": 0.7837535634777528
},
{
"move": 0.05665004788714745
}
],
]
const flatObj = (arr) => {
const flatObject = {};
const keys = ["ticker", "5", "10", "90", "120", "250", "500"]
for (let i = 0; i < arr.length; i++) {
for (const property in arr[i]) {
flatObject[keys[i]] = arr[i][property];
}
};
return flatObject;
}
const result = arr.map(ar => flatObj(ar))
console.log(result)
I'm using mongoose.
Just like 'Mysql Join',
I want to get the data that merge the parents and children collection below.
Parent
[
{
type: "A",
results: [
{
"id": 111111
},
{
"id": 222222
}
]
},
{
type: "B",
results: [
{
"id": 333333
},
{
"id": 444444
}
]
}
]
Child
[
{
dataId: 111111,
results: [
{ "status": { key: "value" } }
]
},
{
dataId: 222222,
results: [
{ "status": { key: "value" } }
]
},
{
dataId: 333333,
results: [
{ "status": { key: "value" } }
]
},
{
dataId: 444444,
results: [
{ "status": { key: "value" } }
]
},
]
Because ObjectId cannot be inserted,
it seems that it cannot be processed using the population method.
I want to merge the two data like Join in MySQL.
like below
Parent.find()
[
{
type: "A",
results: [
{
"id": 111111,
results: [
{ "status": { key: "value" } }
]
},
{
"id": 222222,
results: [
{ "status": { key: "value" } }
]
}
]
},
{
type: "B",
results: [
{
"id": 333333,
results: [
{ "status": { key: "value" } }
]
},
{
"id": 444444,
results: [
{ "status": { key: "value" } }
]
}
]
}
]
You can use this query:
$unwind to get every result from the array to merge with the Child dataid.
$lookup which is the "join" in mongodb. Here query is mergin field id into results from the Parent with dataId from the Child.
$unwind again because $lookup creates an array.
$group to group the values according the id.
$project (this stage is optional) to not shown fields you don't want.
yourParentModel.aggregate([
{
"$unwind": "$results"
},
{
"$lookup": {
"from": "Child",
"localField": "results.id",
"foreignField": "dataId",
"as": "child_results"
}
},
{
"$unwind": "$child_results"
},
{
"$group": {
"_id": "$_id",
"type": {
"$first": "$type"
},
results: {
"$push": "$child_results"
}
}
},
{
"$project": {
"_id": 0,
"results._id": 0
}
}
])
Example here
you could do this from javascript directly
first you get the parent from mongoDB
( use mongoose find method)
let parents = [
{
type: "A",
results: [
{
id: 111111,
},
{
id: 222222,
},
],
},
{
type: "B",
results: [
{
id: 333333,
},
{
id: 444444,
},
],
},
];
then you get the child from the database
let children = [
{
dataId: 111111,
results: [{ status: { key: "value" } }],
},
{
dataId: 222222,
results: [{ status: { key: "value" } }],
},
{
dataId: 333333,
results: [{ status: { key: "value" } }],
},
{
dataId: 444444,
results: [{ status: { key: "value" } }],
},
];
and the treatement to merge the parents with the children will be something like this
for (let parent of parents) {
for (let objectId of parent.results) {
for (let child of children) {
if (child.dataId === objectId.id) {
objectId.results = child.results;
break;
}
}
}
}
const { Parser, transforms: { unwind } } = require('json2csv');
const myCars = [
{
"carModel": "BMW",
"price": 15000,
"items": [
{
"name": "airbag",
"color": "white"
}, {
"name": "dashboard",
"color": "black"
}
]
}, {
"carModel": "Porsche",
"price": 30000,
"items": [
{
"name": "airbag",
"items": [
{
"position": "left",
"color": "white"
}, {
"position": "right",
"color": "gray"
}
]
}, {
"name": "dashboard",
"items": [
{
"position": "left",
"color": "gray"
}, {
"position": "right",
"color": "black"
}
]
}
]
}
];
const fields = ['carModel', 'price', 'items.name', 'items.color', 'items.items.position', 'items.items.color'];
const transforms = [unwind({ paths: ['items', 'items.items'], blankOut: true })];
const json2csvParser = new Parser({ fields, transforms });
const csv = json2csvParser.parse(myCars);
console.log(csv);
Will output
"carModel","price","items.name","items.color","items.items.position","items.items.color"
"BMW",15000,"airbag","white",,
,,"dashboard","black",,
"Porsche",30000,"airbag",,"left","white"
,,,,"right","gray"
,,"dashboard",,"left","gray"
,,,,"right","black"
I want to change all the GRAY to black as the CSV,
What would the best way to be then to convert the CSV back to the original JSON
I have a list of team objects which consists team name, reported by and list of statuses for each day of that team which I would like to convert it into list of date based objects which contains all teams and its status for the respective date.
I have tried something like this which is not giving expected results.
teams.map(team => ({
day: team.statuses.reduce((acc, it) => it.day),
teams: {
teamName: team.teamName
}
}))
[
{
"teamName":"abc",
"reportedBy": "user1",
"statuses":[
{
"day":"10/12",
"status":"green"
},
{
"day":"10/11",
"status":"green"
},
{
"day":"10/09",
"status":"green"
}
]
},
{
"teamName":"xyz",
"reportedBy": "user2",
"statuses":[
{
"day":"10/12",
"status":"red"
},
{
"day":"10/11",
"status":"red"
},
{
"day":"10/09",
"status":"red"
}
]
}
]
Expected Output:
[
{
"day": "1012",
"teams": [
{
"teamName": "abc",
"reportedBy": "user1",
"status": "green"
},
{
"teamName": "xyz",
"reportedBy": "user2",
"status": "red"
}
]
},
{
"day": "1011",
"teams": [
{
"teamName": "abc",
"reportedBy": "user1",
"status": "green"
},
{
"teamName": "xyz",
"reportedBy": "user2",
"status": "red"
}
]
},
{
"day": "1009",
"teams": [
{
"teamName": "abc",
"reportedBy": "user1",
"status": "green"
},
{
"teamName": "xyz",
"reportedBy": "user2",
"status": "red"
}
]
}
]
I don't think reduce is the best option here. I think it's better to create an empty array and populate as you go:
let input = [
{
"teamName":"abc",
"reportedBy": "user1",
"statuses":[
{
"day":"10/12",
"status":"green"
},
{
"day":"10/11",
"status":"green"
},
{
"day":"10/09",
"status":"green"
}
]
},
{
"teamName":"xyz",
"reportedBy": "user2",
"statuses":[
{
"day":"10/12",
"status":"red"
},
{
"day":"10/11",
"status":"red"
},
{
"day":"10/09",
"status":"red"
}
]
}
];
let output = [];
input.forEach(team =>
{
let name = team.teamName;
let reporter = team.reporter
team.statuses.forEach(status =>
{
let dayItem = output.find(item => item.day == status.day);
if(dayItem == null)
{
let newItem = {day: status.day, teams:[{status: status.status, reportedBy: reporter, teamName: name}]};
output.push(newItem);
}
else
{
dayItem.teams.push({status: status.status, reportedBy: reporter, teamName: name})
}
});
});
console.log(JSON.stringify(output));
I have tried something like following.
let dayIndexed = {};
let dayStatuses = [];
teams.forEach(function(team) {
team.statuses.forEach(function(status) {
status.day = status.day.replace(/\//g, '');
if(!dayIndexed[status.day]) {
dayIndexed[status.day] = {
day: status.day,
teams: []
};
dayStatuses.push(dayIndexed[status.day]);
}
dayIndexed[status.day].teams.push({
teamName: team.teamName,
reportedBy: team.reportedBy,
status: status.status
});
});
});