I am currently working on a chatbot based on IBM Watson conversations.
And I'm struggling getting the key out of the enginePower in the filter.
I need every key to be displayed in the chat. So a user can select one.
The structure looks like that:
"filter": {
"enginePower": [{
"key": "55",
"text": "55 kW (75 PS)",
"selectable": false
},
{
"key": "65",
"text": "65 kW (88 PS)",
"selectable": false
},
{
"key": "66",
"text": "66 kW (90 PS)",
"selectable": false
},
{
"key": "81",
"text": "81 kW (110 PS)",
"selectable": false
}]
}
Thanks in advance.
Short answer:
Your key values are: <? T(String).join( ",", $filter.get('enginePower').![key] ) ?>
Broken down
$filter.get('enginePower')
This will return the enginePower as an array containing all your objects.
.![key]
This will return the "Key" field values as an array.
T(String).join( ",", XXX )
This will convert your array XXX into a comma delimited list.
So your final output will say:
Your key values are: 55,65,66,81
Just to add to this. You can only get a single key/value list. If you want to capture a value of a different attribute using a key lookup, then you need to loop.
So for example, start by setting a counter to 0. Then have your node check for $filter.enginePower.size() > $counter.
Within that node, you set "multiple responses" on. Then for the first condition you set $filter.enginePower[$counter].selectable == true. This will allow you to take action if that field is true.
After this you need to create a child node, and have the parent node jump to it. Within the child node response put <? $counter = $counter + 1 ?>. Lastly have the child node jump back to the parent node.
This will loop through the array. Warning! You can only loop 50 times before the loop will end. This is to stop potential endless loops.
Realistically though, you can easily solve all this by formatting the data correctly at the application layer.
Related
I have this json file below and I want to be able to loop through and print the corresponding value. e.g If I send a params "en", I should be able to print Unjha.
[
{
"apmc_code":1000,
"en":"Unjha",
"mr":"उंझा",
"hi":"उंझा",
"pa":"ਉਂਝਾ",
"gu":"ઊંઝા",
"te":"ఉంఝా",
"kn":"ಉಂಜಾ",
"ta":"உன்ஜா",
"ml":"ഉൻഝാ"
},
{
"apmc_code":1001,
"en":"Jamnagar",
"mr":"जामनगर",
"hi":"जामनगर",
"pa":"ਜਾਮਨਗਰ",
"gu":"જામનગર",
"te":"జామ్నగర్",
"kn":"ಜಾಮ್ನಗರ",
"ta":"ஜாம்நகர்",
"ml":"ജാംനഗർ"
},
]
Any help?
iterate over outer-list
iterate over item-map
print map.key = map.value
I have many json resources similar to the below one. But, I need to only fetch the json resource which satisfies the two conditions:
(1) component.code.text == Diastolic Blood Pressure
(2) valueQuantity.value < 90
This is the JSON object/resource
{
"fullUrl": "urn:uuid:edf9439b-0173-b4ab-6545 3b100165832e",
"resource": {
"resourceType": "Observation",
"id": "edf9439b-0173-b4ab-6545-3b100165832e",
"component": [ {
"code": {
"coding": [ {
"system": "http://loinc.org",
"code": "8462-4",
"display": "Diastolic Blood Pressure"
} ],
"text": "Diastolic Blood Pressure"
},
"valueQuantity": {
"value": 81,
"unit": "mm[Hg]",
"system": "http://unitsofmeasure.org",
"code": "mm[Hg]"
}
}, {
"code": {
"coding": [ {
"system": "http://loinc.org",
"code": "8480-6",
"display": "Systolic Blood Pressure"
} ],
"text": "Systolic Blood Pressure"
},
"valueQuantity": {
"value": 120,
"unit": "mm[Hg]",
"system": "http://unitsofmeasure.org",
"code": "mm[Hg]"
}
} ]
},
}
JSON file
I need to write a condition to fetch the resource with text: "Diastolic Blood Pressure" AND valueQuantity.value > 90
I have written the following code:
def self.hypertension_observation(bundle)
entries = bundle.entry.select {|entry| entry.resource.is_a?(FHIR::Observation)}
observations = entries.map {|entry| entry.resource}
hypertension_observation_statuses = ((observations.select {|observation| observation&.component&.at(0)&.code&.text.to_s == 'Diastolic Blood Pressure'}) && (observations.select {|observation| observation&.component&.at(0)&.valueQuantity&.value.to_i >= 90}))
end
I am getting the output without any error. But, the second condition is not being satisfied in the output. The output contains even values < 90.
Please anyone help in correcting this ruby code regarding fetching only, output which contains value<90
I will write out what I would do for a problem like this, based on the (edited) version of your json data. I'm inferring that the full json file is some list of records with medical data, and that we want to fetch only the records for which the individual's diastolic blood pressure reading is < 90.
If you want to do this in Ruby I recommend using the JSON parser which comes with your ruby distro. What this does is it takes some (hopefully valid) json data and returns a Ruby array of hashes, each with nested arrays and hashes. In my solution I saved the json you posted to a file and so I would do something like this:
require 'json'
require 'pp'
json_data = File.read("medical_info.json")
parsed_data = JSON.parse(json_data)
fetched_data = []
parsed_data.map do |record|
diastolic_text = record["resource"]["component"][0]["code"]["text"]
diastolic_value_quantity = record["resource"]["component"][0]["valueQuantity"]["value"]
if diastolic_value_quantity < 90
fetched_data << record
end
end
pp fetched_data
This will print a new array of hashes which contains only the results with the desired values for diastolic pressure. The 'pp' gem is for 'Pretty Print' which isn't perfect but makes the hierarchy a little easier to read.
I find that when faced with deeply nested JSON data that I want to parse in Ruby, I will save the JSON data to a file, as I did here, and then in the directory where the file is, I run IRB so I can just play with accessing the hash values and array elements that I'm looking for.
I'm trying to use jq to selectively change a single property of an object nested in an array, keeping the rest of the array intact. The generated property value needs to refer up to a property of the parent object.
As an example, take this array:
[
{
"name": "keep_me"
},
{
"name": "leave_unchanged",
"list": [
{
"id": "1",
"key": "keep_this"
}
]
},
{
"name": "a",
"list": [
{
"id": "2",
"key": "also_keep_this"
},
{
"id": "42",
"key": "replace_this"
}
]
}
]
I want to change the value of the last key (replace_this), using the name property of the parent object to generate a value like generated_value_for_a_42.
The key problem here seems to be leaving the rest of the array unmodified, while updating specific elements. But the need to refer 'up the tree' to a parent property complicates matters.
I tried wrapping changes in parentheses to keep untouched elements, but then had trouble with variable binding (using as) to the right scope, for accessing the parent property. So I either ended up discarding parts of the array or objects, or getting errors about the variable binding.
This answer helped me in the right direction. The important learnings were to use |= in the right place, and have the filters wrapped in if p then f else . to keep the unchanged elements.
The following jq script solves the task:
map(.name as $name |
if has("list")
then .list |= map(if .key | contains("keep") | not
then .key = "generated_value_for_" + $name + "_" + .id
else .
end)
else .
end)
I have a table like:
id: integer,
... other stuff...,
comments: array of jsonb
where the comments column has the following structure:
[{
"uid": "comment_1",
"message": "level 1 - comment 1",
"comments": [{
"uid": "subcomment_1",
"message": "level 2 - comment 1",
"comments": []
}, {
"uid": "subcomment_2",
"message": "level 1 - comment 2",
"comments": []
}]
},
{
"uid": "P7D1hbRq4",
"message": "level 1 - comment 2",
"comments": []
}
]
I need to update a particular field, for example:comments[1](with uid = comment_1) -> comments[2] (with uid = subcomment_2) -> message = 'comment edited'.
I'm brand new to postgresql and I can't figure it out how to do this, not even close. I manage to merge objects and change message for level 1 with:
UPDATE tasks
set comments[1] = comments[1]::jsonb || $$
{
"message": "something",
}$$::jsonb
where id = 20;
but that's as far as I could go.
Any hints towards the right direction?
LE:
I got this far:
UPDATE tasks
set comments[1] = jsonb_set(comments[1], '{comments,1, message}', '"test_new"')
where id = 20;
Sure, I can get this path from javascript but it's that a best practice? Not feeling comfortable using indexes from javascript arrays.
Should I try to write a sql function to get the array and use the 'uid' as key? Any other simpler way to search/select using the 'uid' ?
LLE
I can't get it to work using suggestion at:this question (which I read and tried)
Code bellow returns nothing:
-- get index for level 2
select pos as elem_index
from tasks,
jsonb_array_elements(comments[0]->'comments') with ordinality arr(elem, pos)
where tasks.id = 20 and
elem ->>'uid'='subcomment_1';
and I need it for several levels so it's not quite a duplicate.
First, you cannot update a part of a column (an element of an array) but only a column as a whole.
Next, you should understand what the path (the second argument of the jsonb_set() function) means.
Last, the third argument of the function is a valid json, so a simple text value must be enclosed in both single and double quotes.
update tasks
set comments = jsonb_set(comments, '{0, comments, 1, message}', '"comment edited"')
where id = 1;
Path:
0 - the first element of the outer array (elements are indexed from
0)
comments - an object with key comments
1 - the second element of
the comments array
message - an object message in the above
element.
See Db<>fiddle.
I have two arrays that need to be combined into a hash. However, one of the arrays will always be the key. So I need to go through a list of names, numbers, addresses, etc and give them all titles. An example would be:
Adjustor name => Chase, Firm name => Chase Bank
and then repeat for another location.
Adjustor name => Rob, Firm name => Walmart.
Here is what I have so far:
Array_headers = ['Adjuster Name','Firm Name', 'Firm Number', 'Adjustment Type', 'Address 1', 'Address 2', 'City', 'State', 'Zip Code', 'Phone', 'Fax', 'Website', 'Comments', 'Latitude', 'Longitude', 'Manual LongLatCalc', 'LongLat Error']
Data_examples = ["AdjusterName", "FirmName", "FirmNumber", "AdjustmentType", "Address1", "Address2", "City", "State", "ZipCode", "Phone", "Fax", "WebSite", "Comments", "Latitude", "Longitude", "ManualLongLatCalc", "LongLatError", "chase", "chase bank", "260-239-1761", "property", "501 w", "200 s", "albion", "in", "46701", "555-555-5555", "c#gamil", "whatsupwhatups.com", "hahahah", "12.332", "12.222", "no", "none"]
CombiningArrays= Hash[Array_headers.zip data_examples]
p CombiningArrays
It should return the following:
{"Adjuster Name"=>"AdjusterName", "Firm Name"=>"FirmName", "Firm Number"=>"FirmNumber", "Adjustment Type"=>"AdjustmentType", "Address 1"=>"Address1", "Address 2"=>"Address2", "City"=>"City", "State"=>"State", "Zip Code"=>"ZipCode", "Phone"=>"Phone", "Fax"=>"Fax", "Website"=>"WebSite", "Comments"=>"Comments", "Latitude"=>"Latitude", "Longitude"=>"Longitude", "Manual LongLatCalc"=>"ManualLongLatCalc", "LongLat Error"=>"LongLatError", *"Adjuster Name"=>" \r\nchase", "Firm Name"=>"chase", "Firm Number"=>"260-239-1761", "Adjustment Type"=>"property", "Address 1"=>"501 w", "Address 2"=>"200 s", "City"=>"albion", "State"=>"in", "Zip Code"=>"46701", "Phone"=>"555-555-5555", "Fax"=>"c#gamil", "Website"=>"whatsupwhatups.com", "Comments"=>"hahahah", "Latitude"=>"12.332", "Longitude"=>"12.222", "Manual LongLatCalc"=>"no", "LongLat Error"=>"none"*}
It stops at "LongLat Error"=>"LongLatError" and everything that is italicized does not show up. How do I get it to continually loop through my other array?
I also tried the following code:
#Creating a method to go through arrays
def array_hash_converter headers, data
hash = Hash.new
headers.each_with_index do |header, index|
hash[header] = data[index]
end
puts hash
end
i=0
while i < data.count do
array_hash_converter Array_header, data
i+=1
end
Please Help!
I suggest to slice the values array on the keys array length, and then just map them into an array of hashes. For example:
sliced_values = Data_examples.each_slice(Array_headers.length)
result = sliced_values.map { |slice| Array_headers.zip(slice).to_h }
You will never get a single hash as result, because you'll have collision on the keys and, then, only the last result will be returned, since it overwrites the previous ones. Remember that hash keys are unique in Ruby.
Looks like you actually want an array of hashes. So, your first array is going to be your list of keys for your hashes (I'll reference to this as "HEADER_KEYS"). In your second array, I see "\r\n". You may want to back up a step. I'm assuming this is coming from a CSV, so there are known delimiters and an unknown number of rows. To start parsing your CSV, split on the "\r\n" (or whatever the line break happens to be), and then iterate over each of those items and split on the commas. Something like:
final_dataset = []
HEADER_KEYS = [].freeze # put your actual array_of_headers here and freeze it
array_of_rows = []
csv_string.split("\r\n").each { |row| array_of_rows.push(row.split) }
This should give you an array of arrays that you can loop over.
array_of_rows.each do |row|
row_hash = {}
HEADER_KEYS.each_with_index do |key, index|
row_hash[key] = row[index]
end
final_dataset.push(row_hash)
end
There may be a more elegant way of handling this, but this should do the trick to get you going.