How to get another key value from an array of json? - json

Lets say I have these arrayed JSON values
[{operation_id: 2, operation_name: FAITHFUL BELIEVERS},
{operation_id: 3, operation_name: SAMPLE OP},
{operation_id: 4, operation_name: SAMPLE OP 2}]
Now I will select the operation name 'SAMPLE OP' but I want to display the value of its operation_id. How would I do that?

Your JSON is a list of maps, so use where on the list to filter it by your predicate. Better still, use firstWhere as we assume there's just one match.
The match function returns true if the operation name member of the map matches.
firstWhere returns the first matching map, and you want the operation id member of that map.
final id = list
.firstWhere((m) => m['operation_name'] == 'SAMPLE OP')['operation_id'];

Related

How can I loop with multiple conditional statements in OpenRefine (GREL)

I am geocoding using OpenRefine. I pulled data from OpenStreetMaps to my datasetstructure of data
I am adding a "column based on this column" for the coordinates.I want to check that the display_name contains "Rheinland-Pfalz" and if it does, I want to extract the latitude and longitude,i.e. pair.lat + ',' + pair.lon. I want to do this iteratively but I don't know how. I have tried the following:
if(display_name[0].contains("Rheinland-Pfalz"), with(value.parseJson()[0], pair, pair.lat + ',' + pair.lon),"nothing")
but I want to do this for each index [0] up to however many there are. I would appreciate if anyone could help.
Edit: Thanks for your answer b2m.
How would I extract the display_name corresponding to the coordinates that we get. I want the output to be display_name lat,lon for each match (i.e. contains "Rheinland-Pfalz", because I have a different column containing a piece of string that I want to match with the matches generated already.
For example, using b2m's code and incorporating the display_name in the output we get 2 matches:
Schaumburg, Balduinstein, Diez, Rhein-Lahn-Kreis, Rheinland-Pfalz, Deutschland 50.33948155,7.9784308849342604
Schaumburg, Horhausen, Flammersfeld, Landkreis Altenkirchen, Rheinland-Pfalz, Deutschland 52.622319,14.5865283
For each row, I have another string in a different column. Here the entry is "Rhein-Lahn-Kreis". I want to filter the two matches above to only keep those containing my string in the other column. In this case "Rhein-Lahn-Kreis" but the other column entry is different for each row. I hope this is clear and I would greatly appreciate any help
Assuming we have the following json data
[
{"display_name": "BW", "lat": 0, "lon": 1},
{"display_name": "NRW 1", "lat": 2, "long": 3},
{"display_name": "NRW 2", "lat": 4, "lon": 5}
]
You can extract the combined elements lat and long with forEach and filter using the following GREL expression e.g. in the Add column based on this column dialog.
forEach(
filter(
value.parseJson(), geodata, geodata.display_name.contains("NRW")
), el, el.lat + "," + el.lon)
.join(";")
This will result in a new field with the value 2,3;4,5.
You can then split the new multi valued field on the semicolon ";" to obtain separated values (2,3 and 4,5).
Another approach would be to split the JSON Array elements into separate rows, avoiding the forEach and filter functions.

Postgres searching through arrays within JSON

Many similar questions, but unfortunately non helped me solve my problem. I tried to && and #> and similar, but no success.
I have a postgres DB with a table, that has a "value" column typed "json". All rows have the same basic structure, a simple JSON object, with the att "value" holding an array of strings:
{
value: ['one', 'two', 'three']
}
I need to make a query accepting an array of strings and returns all the rows, in which the value array and the passed array of strings have at least one common element.
Following the upper example, if I send ['one', 'four'], it should return the row with value: ['one', 'two', 'three'], since there is an intersection - 'one'.
If I send the array ['four', 'five', 'six'], it will not return this row.
You can use the ?| operator for that. But as you are using json and not the recommended jsonb type, you need to cast your column:
select *
from the_table
where (value::jsonb -> 'value') ?| array['one', 'four']

Mysql for NodeJS not expanding array in queries

I'm using NodeJS and the mysql package from npm. I'm having trouble selecting specific rows from the database by ID. I'm using a simple WHERE id IN (...) query, and passing in the ids as an array of numbers.
According to the documentation,
Arrays are turned into list, e.g. ['a', 'b'] turns into 'a', 'b'
So I've written this code to debug the SQL it generates:
console.log(ids);
console.log(this.connection.format(
"SELECT `invitations`.* FROM `invitations` WHERE `invitations`.`id` IN (?)",
ids
));
I expect to see a list of ids first, then the SQL statement where those ids are in the IN section of the query.
However, only the first id is present in the query:
console.log tests/fakers/InvitationFaker.ts:70
[ 207, 208 ]
console.log tests/fakers/InvitationFaker.ts:71
SELECT `invitations`.* FROM `invitations` WHERE `invitations`.`id` IN (207)
Why doesn't the query look like this:
... WHERE `invitations`.`id` IN (207, 208)
?
try to convert the ids to string with "," between the ids
this.connection.format(
"SELECT `invitations`.* FROM `invitations` WHERE `invitations`.`id` IN (?)",
ids.join(",")
));
I'm an idiot :) I forgot that the second argument can be either a single value or an array, but when it's an array, the first value fills the first ? and so on. To expand an array, I need to do this:
" ... WHERE `id` IN ?", [ids]
(note the double array, since ids is already an array). For example:
" ... WHERE `id` IN ?", [[1, 2, 3, 4]]

How to iterate over a nested json array and change the node properties based on a condition?

I want to create new properties for a pre-existing node based on a condition. To be more specific, I want to create a new node property when a node property matches with a property within the nested JSON array. my json structure looks something like this:
{"some tasks":[
{"id":1,"name":"John Doe"},
{"id":2,"name":"Jane Doe"}
],
"some links":[
{"id":1,"type":"cartoon"}
{"id":2,"type":"anime"}
]
}
I already created nodes with properties from tasks - now I want to iterate over the links part and update the properties of the node when the ids match. I tried using foreach like so-
call apoc.load.json("file:///precedence.json")yield value as line
foreach(link in line.link| match (n) where n.id=link.source)
return n
which returns the error-
Neo.ClientError.Statement.SyntaxError: Invalid use of MATCH inside FOREACH (line 2, column 28 (offset: 93))
"foreach(link in line.link| match (n) where n.id=link.source)"
so how do i check this condition inside foreach?
You can't use a MATCH inside a FOREACH, it only allows updating clauses.
Instead you can UNWIND the list back into rows (you'll have a row per entry in the list) then you can MATCH and SET as needed.
I also highly recommend using labels in your query, and ensuring you have in index on the label and id property for fast lookups. For this example I'll use :Node as the label (so for the example you would have :Node(id) for the index):
CALL apoc.load.json("file:///precedence.json") yield value as line
UNWIND line.link as link
MATCH (n:Node)
WHERE n.id = link.source
SET n.type = link.type

CSV Parser through angularJS

I am building a CSV file parser through node and Angular . so basically a user upload a csv file , on my server side which is node the csv file is traversed and parsed using node-csv
. This works fine and it returns me an array of object based on csv file given as input , Now on angular end I need to display two table one is csv file data itself and another is cross tabulation analysis. I am facing problem while rendering data, so for a table like
I am getting parse responce as
For cross tabulation we need data in a tabular form as
I have a object array which I need to manipulate in best possible way so as to make easily render on html page . I am not getting a way how to do calculation on data I get so as to store cross tabulation result .Any idea on how should I approach .
data json is :
[{"Sample #":"1","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"2","Gender":"Male","Handedness;":"Left-handed;"},{"Sample #":"3","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"4","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":"5","Gender":"Male","Handedness;":"Left-handed;"},{"Sample #":"6","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":"7","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"8","Gender":"Female","Handedness;":"Left-handed;"},{"Sample #":"9","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":";"}
There are many ways you can do this and since you have not been very specific on the usage, I will go with the simplest one.
Assuming you have an object structure such as this:
[
{gender: 'female', handdness: 'lefthanded', id: 1},
{gender: 'male', handdness: 'lefthanded', id: 2},
{gender: 'female', handdness: 'righthanded', id: 3},
{gender: 'female', handdness: 'lefthanded', id: 4},
{gender: 'female', handdness: 'righthanded', id: 5}
]
and in your controller you have exposed this with something like:
$scope.members = [the above array of objects];
and you want to display the total of female members of this object, you could filter this in your html
{{(members | filter:{gender:'female'}).length}}
Now, if you are going to make this a table it will obviously make some ugly and unreadable html so especially if you are going to repeat using this, it would be a good case for making a directive and repeat it anywhere, with the prerequisite of providing a scope object named tabData (or whatever you wish) in your parent scope
.directive('tabbed', function () {
return {
restrict: 'E',
template: '<table><tr><td>{{(tabData | filter:{gender:"female"}).length}}</td></tr><td>{{(tabData | filter:{handedness:"lefthanded"}).length}}</td></table>'
}
});
You would use this in your html like so:
<tabbed></tabbed>
And there are ofcourse many ways to improve this as you wish.
This is more of a general data structure/JS question than Angular related.
Functional helpers from Lo-dash come in very handy here:
_(data) // Create a chainable object from the data to execute functions with
.groupBy('Gender') // Group the data by its `Gender` attribute
// map these groups, using `mapValues` so the named `Gender` keys persist
.mapValues(function(gender) {
// Create named count objects for all handednesses
var counts = _.countBy(gender, 'Handedness');
// Calculate the total of all handednesses by summing
// all the values of this named object
counts.Total = _(counts)
.values()
.reduce(function(sum, num) { return sum + num });
// Return this named count object -- this is what each gender will map to
return counts;
}).value(); // get the value of the chain
No need to worry about for-loops or anything of the sort, and this code also works without any changes for more than two genders (even for more than two handednesses - think of the aliens and the ambidextrous). If you aren't sure exactly what's happening, it should be easy enough to pick apart the single steps and their result values of this code example.
Calculating the total row for all genders will work in a similar manner.