I want to build a json request required for JIT SpaceTree.
The workflow: a question is started with the id of the retrospective answer stored.
If the option is yes then it loads the next question based on the load_yes value. this load_yes value selects the id and loads that question.
If the option is no it loads the next no based question by its id stored under load_no,
json should look like:
var json = {
id: "start",
name: "does test work?",
data: {},
children: [{
id: "layer1_1",
name: "option: no, id 3, Q: test does work with option no?",
data: {},
children: []
}, {
id: "layer1_2",
name: "option: yes, id 2, Q: test does work!!",
data: {},
children: [{
id: "layer2_1",
name: "option: no, id 4, Q: test does work?",
data: {},
children: []
}, {
id: "layer2_2",
name: "option: yes, id 5, Q: ",
data: {},
children: []
}]
}]
};
$query = $mysqli->query("SELECT * FROM topic_answer");
while($obj = $query->fetch_object()){
$arr[] = array(
'id' => $obj->id,
'name' => $obj->topic_question,
'data' => '',
'children' => array(array(
'id' => $obj->load_yes,
'name' => $obj->load_yes,
'data' => '',
'children' =>array(),
),array(
'id' => $obj->load_no,
'name' => $obj->load_no,
'data' => '',
'children' => array(),
),
)
);
id, topic_name, topic_creator, topic_question, load_yes, start, load_no, end
1 test jordan does test work? 2 1 3 0
4 test jordan test does work no 0 0 0 0
5 test jordan test does work yes 0 0 0 0
2 test jordan test does work yes!! 4 0 5 0
in json, objects are depicted as {}. so basically what this code means is an array of objects:
[
{},
{}
]
so here, where you are nesting arrays:
'children' => array(array(
'id' => $obj->load_yes,
'name' => $obj->load_yes,
'data' => '',
'children' =>array(),
),array(
'id' => $obj->load_no,
'name' => $obj->load_no,
'data' => '',
'children' => array(),
),
)
you actually want to replace the inner array by an object, such as stdClass(). stdClass is used like this:
$obj = new stdClass();
$obj->id = "layer1_1";
$obj->name = "option: no, id 3, Q: test does work with option no?";
$obj->data = new stdClass();
$obj->children = array();
then, with php
'children' => array(
$obj1,
$obj2,
),
Related
I have this array:
$arr = array(
'reportDescription' => array(
'reportSuiteID' => 'globretailprod',
'elements' => array(
0 => array(
'id' => $queryElement
)
),
'metrics' => array(
0 => array(
'id' => $queryMetric
)
)
)
);
I'm trying to insert some code into the array using an if command. This is what I have:
if (isset($querySegment)) {
$arr['reportDescription']['segments'] = $querySegment;
}
However that gives me the wrong result, what I am trying to achieve is this:
{
"reportDescription": {
"reportSuiteID": "rbsglobretailprod",
"dateFrom": "2018-09-09",
"dateTo": "2018-09-10",
"dateGranularity": "day",
"metrics": [{
"id": "pageviews"
}],
"elements": [{
"id": "page"
}],
"segments": [{
"id": "jjj"
}]
}
}
Notice there are two issues with this. Firstly, segments isn't isn't insert with an id, it's just inserted as a value. Secondly, I am a bit concerned about the trailing comma after metrics in my original array, since I need to be able to add a comma after the metrics array if I do include segments.
Just use the same format as you use for the other items to get the same structure...
if (isset($querySegment)) {
$arr['reportDescription']['segments'] = array(
0 => array(
'id' => $querySegment
)
);
}
As for the comma, this should be added automatically as needed if your using json_encode()
In PHP I use the array_column() function a lot as it allows me to retrieve values from a specific column inside an array returned themselves in a nice array, for example, using this array:
$users = [
[
'id' => 1,
'name' => 'Peter'
],
[
'id' => 2,
'name' => 'Paul'
],
[
'id' => 3,
'name' => 'John'
]
];
Doing array_column($users, 'name') will return:
Array
(
[0] => Peter
[1] => Paul
[2] => John
)
Since transitioning to Python I still haven't found a built in function that I can use to do the same thing on a list of dicts for example.
Does such a function exist and if not, what is the best way to achieve this?
You can use a list comprehension to extract the 'column' of interest. There is no direct Python function to my knowledge. List comprehensions are almost always faster than using map. Python List Comprehension Vs. Map
users = [
{
'id': 1,
'name': 'Peter'
},
{
'id': 2,
'name': 'Paul'
},
{
'id': 3,
'name': 'John'
}
]
>>> [(user.get('id'), user.get('name')) for user in users]
[(1, 'Peter'), (2, 'Paul'), (3, 'John')]
Or using an enumerated index location instead of the id field:
>>> [(n, user.get('name')) for n, user in enumerate(users)]
[(0, 'Peter'), (1, 'Paul'), (2, 'John')]
Or just the names...
>>> [user.get('name') for user in users]
['Peter', 'Paul', 'John']
Something like this?
arr = [
{
'id' : 1,
'name' : 'Peter'
},
{
'id' : 2,
'name' : 'Paul'
},
{
'id' : 3,
'name' : 'John'
}
]
list(map(lambda x: x["name"], arr))
I'm using an API that requires me to put an array in a form field. The example given is in PHP, but I'm using NodeJS. The API expects one of the fields to be an array, and I'm having a hard time figuring out how to do this.
The PHP example looks like this:
$request->buildPostBody(array(
'reference' => array(
'line1' => 'Soundboard Setup',
'line2' => 'Thank you for the order',
'line3' => 'Our reference is: 3993029/11BD'
),
'lines' => array(
array('amount' => 50,
'amount_desc' => 'panels',
'description' => 'Sound buttons',
'tax_rate' => 21,
'price' => 5.952
),
array('amount' => 1,
'amount_desc' => '',
'description' => 'Wooden case',
'tax_rate' => 21,
'price' => 249
),
array('amount' => 10,
'amount_desc' => 'hours',
'description' => 'Support',
'tax_rate' => 6,
'price' => 62.5
),
array('description' => 'This is a textline'))
));
In NodeJS it I've tried this (among other things):
var formData = {
reference: [{'line1':'something'}], // <- this isn't going to fly
lines: [{
'amount': amount,
'amount_desc': 'amount_desc',
'description': 'description',
'tax_rate': 0,
'price': 100
}]
};
request.post({
url: 'https://www.factuursturen.nl/api/v1/invoices/',
formData: formData,
headers: {
'Authorization': 'Basic ' + new Buffer(user + ':' + key).toString('base64')
}
}, function (error, response, body) {
if (!error && [200, 201, 204].indexOf(response.statusCode) > 0) {
console.log('posted ': ', response.statusCode);
} else {
console.log('problem with request: ', error, response.statusCode, body);
}
}
);
When I try to pass an object like so: reference: {'line1':'foo'} I get an error from Node:
node_modules/request/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js:33
source.on('error', function() {});
^
TypeError: Object #<Object> has no method 'on'
How would I best go about shoehorning this round peg into that square hole?
In PHP arrays can be arrays and they can be associative arrays, which are essentially objects in JavaScript.
Specifying with array()
An array can be created using the array() language construct. It takes any number of comma-separated key => value pairs as arguments.
array(
key => value,
key2 => value2,
key3 => value3,
...
)
In JavaScript the above would essentially be just an object
{
key: 'value',
key2: 'value2'
key3: 'value3'
...
}
It will not be an object wrapped inside an array [{…}], which is what you're doing with your reference
So to mimic the PHP structures your data should be like this:
var formData = {
reference: {'line1':'something'}, // <- this should work now
lines: [{ // <- this is still an array of objects [{}], as in PHP too, it's a nested array
amount: amount,
'amount_desc': 'amount_desc',
'description': 'description',
'tax_rate': 0,
'price': 100
}]
};
But that causes another problem as you have noticed.
When I try to pass an object like so: reference: {'line1':'foo'} I get an error from Node:
node_modules/request/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js:33
source.on('error', function() {});
^
TypeError: Object #<Object> has no method 'on'
This error is explain here: https://github.com/request/request/issues/1495
Basically form-data only takes simple object probably only 1 level deep.
Try this:
var formData = {
'reference.line1': 'something',
'lines[0].amount': amount,
'lines[0].amount_desc': 'amount_desc',
'lines[0].description': 'description',
'lines[0].tax_rate': 0,
'lines[0].price': 100,
};
I have a deeply nested PHP array which I saved as a document in Mongo and ended up with this structure:
{
"_id" : "...",
"categ1" : {
"aaa" : 112.6736,
"bbb" : 83.9137,
"ccc" : 80.3322,
.....
},
"categ2" : {
"xxx" : 1,
"yyy" : 22,
"zzz" : 7,
"subcateg" : {
"sub1" : 1,
"sub2" : 22
}
}
}
Now, I have another array with a similar structure and I would like to increase the values of the record, by the values of the modifier array:
$modifier=array(
'categ1' => array(
'aaa' => 3,
'bbb' => -1,
'mmm' => 11
),
'categ2' => array(
'yyy' => -2,
'subcateg' => array(
'sub1' => -1
)
)
);
How can I increase the values inside the document by the values of the $modifier all at once, in a single query, and without loading the entire document ?
I've looked around the web but couldn't find any info on this.
Also, i'm pretty newbie at Mongo. Thanks
You can get your $modifier array to look like this:
$modifier = array(
'categ1.aaa' => 3,
'categ1.bbb' => -1,
'categ1.mmm' => 11,
'categ2.yyy' => -2,
'categ2.subcateg.sub1' => -1
)
Link for how to get that.
Then you should be able to simply use:
$col->update(
array("_id" => "..."),
array('$inc' => $modifier),
array("upsert" => true)
);
So my code here:
$featurecollection = ("FeatureCollection");
$test[] = array (
"type" => $featurecollection,
$features[] = array($images)
);
file_put_contents($cache,json_encode($test));
results in the following json:
[
{
"type":"feature",
"0":[
[
{
"title":"some title",
"src":"value",
"lat":"value",
"lon":"value"
},
{
"title":"some title",
...
But I need to nest things differently and I'm perplexed on how the php array should be constructed in order to get a result like:
{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"geometry":{
"coordinates":[
-94.34885,
39.35757
],
"type":"Point"
},
"properties":{
"latitude":39.35757,
"title":"Kearney",
"id":919,
"description":"I REALLY need new #converse, lol. I've had these for three years. So #destroyed ! :( Oh well. Can't wait to get a new pair and put my #rainbow laces through. #gay #gaypride #bi #proud #pride #colors #shoes #allstar #supporting ",
"longitude":-94.34885,
"user":"trena1echo5",
"image":"http://images.instagram.com/media/2011/09/09/ddeb9bb508c94f2b8ff848a2d2cd3ece_7.jpg",
"instagram_id":211443415
}
},
What would the php array look like for that? I'm thrown off by the way everything is nested but still has a key value.
Here's how I'd represent that in PHP:
array(
'type' => 'FeatureCollection',
'features' => array(
array(
'type' => 'Feature',
'geometry' => array(
'coordinates' => array(-94.34885, 39.35757),
'type' => 'Point'
), // geometry
'properties' => array(
// latitude, longitude, id etc.
) // properties
), // end of first feature
array( ... ), // etc.
) // features
)
So to get that structure, each feature has to be an associative array of:
type,
geometry - an associative array of:
coordinates - an indexed array of values,
type
properties - an associative array of values like latitude, longitude, id etc.
It's times like these when I prefer languages that distinguish between lists (array(1, 2, 3)) and dictionaries or maps (array('a' => 1, 'b' => 2)).
With PHP 5.4 and above:
$array = [
'type' => 'FeatureCollection',
'features' => [
[
'type' => 'Feature',
'geometry' => [
'coordinates' => [-94.34885, 39.35757],
'type' => 'Point'
], // geometry
'properties' => [
// latitude, longitude, id etc.
] // properties
], // end of first feature
[] // another feature, and so on
] // end of features
];
For the PHP script below:
<?php
header('Content-type=> application/json');
echo json_encode($array);
This is the JSON output;
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"coordinates": [
-94.34885,
39.35757
],
"type": "Point"
},
"properties": []
},
[]
]
}