How to perform JSON object updates using jq commandline utility - javascript

I have a JSON object as follows
{"Sample" : [{ "key": "KeyName", "values": [ [1025409600000,
10], [1028088000000, -6.3382185140371]
] }]}
Using javascript I can modify any values as follows
data.Sample[0].values.push([1028088000000,0]);
How to perform the similar operation using jq commandline json processor? So the JSON object becomes
{"Sample" : [{ "key": "KeyName", "values": [ [1025409600000, 10],
[1028088000000, 0] ] }]}
Thank you.

As it stands there is a bug in the question, as Javascript's Array.push appends to an array.
The jq equivalent of the given expression:
data.Sample[0].values.push([1028088000000,0]);
would be:
.Sample[0].values += [[1028088000000,0]]
or if you want to use the Javascript syntax, you could define def push(x): .[length] = x;
If you want to replace the last value in the values array by another value, say $x, you could (using jq 1.5 or later) write:
.Sample[0].values[-1] = $x
A more robust (with respect to different jq releases) approach would be:
.Sample[0].values |= (.[length-1] = $x)
With jq 1.5 or later, if you wanted only to change the negative number to 0, you would write:
.Sample[0].values[-1][-1] = 0
Etc.

Related

Converting a string to a list and seperate each element

So I have a use case in which I enter indexes and descriptions which belong to a round. I created a JS function that allows me to enter these indexes and descriptions. When I strip the data from the post request I get the following data:
['0,This is a testround', '1,This is a new testround']
I want to split this data so that I can seperate the 0 in an index variable and the following description "This is a testround" in a description variable. Please note that the description can only contain comma's. The indexes are not always corresponding with the indexes of an array: [[0,"Description1"],[5,"Description2"]] could happen
A possible solution could be to split the string on a comma and use str[0] for the index and the other parts for the description but to me this would look like an ugly solution.
What should I do?
I use the following JS to save the rounds to a playerdata div from which i extract the list above (in which items is the list with the index and description)
function item_checkbox(items,n) {
return `
<input type="checkbox" style="display:none;" name="${itemList[n]}" value="${items}" checked>
`
}
function add_to_itemData(items, n) {
itemDataEl = document.getElementById(itemData[n])
itemDataEl.innerHTML = itemDataEl.innerHTML + item_checkbox(items, n)
}
Thanks for any help in advance
While you say that it would be an "ugly" solution to solve it by splitting, I think it's a pretty straightforward routine, given the format the data is returned to you.
['0,This is a testround', '1,This is a new testround'].map(v => v.split(','));
... would translate correctly to:
[
[ "0", "This is a testround" ],
[ "1", "This is a new testround" ]
]
But I guess I get what you mean. There are a few possible problems - for example, that of key uniqueness. You could solve this one by keeping each row into Javascript objects instead of arrays, and you can convert it quite easily by using Object.fromEntries(), since it conveniently accepts each row of bidimensional arrays as key/value pairs:
Object.fromEntries([
[ "0", "This is a testround" ],
[ "1", "This is a new testround" ],
[ "1", "This is a dupe testround" ] // this will overwrite the previous entry
]);
// {0: "This is a testround", 1: "This is a dupe testround"}
You might want to take a few extra steps for additional control, like using .trim() to remove leading or trailing whitespaces or testing/filtering/splitting them using a custom regex.

How to access an attribute from a JSON line saved in a position from an array?

This may be a very simple question but I really can't seem to make it work.
I have several JSON lines and a notes array.
Using notes.push(JSONline) I am saving one JSON line per array position, I assume, so in the following manner:
//notes[1]
{"id":"26","valuee":"20","datee":"2016-04-05T15:15:45.184+0100","id2":51}
//notes[2]
{"id":"27","valuee":"134","datee":"2016-04-05T15:15:47.238+0100","id2":53}
//notes[3]
{"id":"26","valuee":"20","datee":"2016-04-05T15:15:45.184+0100","id2":52}
Here is my problem: I want to print one specific attribute, for example id from one specific JSON line in the array. How can I do this?
When I do console.log(notes) it prints all the JSON lines just as expected. But if I do console.log(notes[1]) it prints the first character of the JSON line in that position, not the whole line.
Similarly console.log(notes[1].id) does not print the id from the first JSON line, in fact it prints 'undefined'.
What am I doing wrong?
Thank you so much.
I'd recommend that you parse all the json when you are pushing to notes, like:
notes.push(JSON.parse(JSONLine))
If you are somehow attached to having json strings in an array instead of objects, which I wouldn't recommend, you could always just parse once you have the jsonLine id
JSON.parse(notes[id]).id
Basically, you want to use JSON.parse for either solution and I'd strongly recommend converting them to objects once at the beginning.
You need to remember that JSON is the string representation of a JS object. JS strings have similar index accessor methods to arrays which is why you can write console.log(notes[0]) and get back the first letter.
JavaScript doesn't allow you to access the string using object notation, however, so console.log(notes[0].id) will not work and the reason you get undefined.
To access the data in the string using this method you need to parse the string to an object first.
var notes = ['{"id":"26","valuee":"20","datee":"2016-04-05T15:15:45.184+0100","id2":51}'];
var note0 = JSON.parse(notes[0]);
var id = note0.id;
DEMO
This leaves the question of why you have an array of JSON strings. While it's not weird or unusual, it might not be the most optimum solution. Instead you could build an array of objects and then stringify the whole data structure to keep it manageable.
var obj0 = {
"id": "26",
"valuee": "20",
"datee": "2016-04-05T15:15:45.184+0100",
id2: 51
};
var obj1 = {
"id": "27",
"valuee": "134",
"datee": "2016-04-05T15:15:47.238+0100",
"id2": 53
}
var arr = [obj0, obj1];
var json = JSON.stringify(arr);
OUTPUT
[
{
"id": "26",
"valuee": "20",
"datee": "2016-04-05T15:15:45.184+0100",
"id2": 51
},
{
"id": "27",
"valuee": "134",
"datee": "2016-04-05T15:15:47.238+0100",
"id2": 53
}
]
You can then parse the JSON back to an array and access it like before:
var notes = JSON.parse(json);
notes[0].id // 26
That's because you have {"id": "value"... as a string in your key value pairs. "id" is a string so you can't reference it like a property. 1. use
var notes = JSON.parse(notes);
as mentioned in the comments by The alpha
or remove the quotes try
{id:"26", ...}
that's why notes[i].id is returning undefined

splitting string by ],[ and creating json objects

I am grabbing values from a textarea with document.getElementById("textarea-id").value. I believe this grabs a object of type string.
var b = document.getElementById("textarea-id").value
I will JSON.stringify(b) because I have quotes in b so this will escape the quotes.
var c = JSON.stringy\ify(b)
I want to test if c is actually a JSON object. If it is, put each JSON object in an array. (there might be multiple JSON objects)
To me the easiest way to do so would be to separate the string by the ],[ values that separate the JSON objects. I'm not sure how to separate each object by ],[ while preserving the brackets.
example JSON object:
[{
"a":1,
"b":2
}],
[{
"c":3,
"d":4
}]
Consider ...
c = c.replace("],[", "]###[");
result = c.split("###");
... by using replace, we are changing the , between the ] [ to something unique that you can then split.

How to pass an array of integers as a parameter from javascript to python?

I have a javascript code that obtains the value of several checked boxes and inserts their value (integers) into an array:
var my_list = $('.item:checked').map(function(){return $(this).attr('name');}).get();
I want to pass this javascript array to a python function as a paramter. This is how I am doing it right now, with ajax and jQuery:
$.ajax({
url : "{{tg.url('/foo/bar')}}",
data : {
my_list: JSON.stringify(my_list),
...
},
On the python side, I have this code, to get the parameters:
item_list = get_paramw(kw, 'my_list', unicode)
This works, but I am not receiving the array as an array of integers, but as a single string containing the "[", "]", "," and """ symbols, which I would have to parse and isn't the most elegant way of dealing with this whole situation I think.
How should it be done to receive a javascript array of integers as an array of integers in python (not as a string)?
The easiest way to send simple arbitrarily-structured data from Javascript to Python is JSON. You've already got the Javascript side of it, in that JSON.stringify(my_list). All you need is the Python side. And it's one line of code:
item_list_json = get_paramw(kw, 'my_list', unicode)
item_list = json.loads(item_list_json)
If item_list in your JS code were the Javascript array of numbers [1, 2, 3, 4], item_list in your Python code would be the Python list of ints [1, 2, 3, 4].
(Well, you also have to import json at the top of your script, so I guess it's two lines.)
The proper way to send multiple values for one key is
data: {
my_list: my_list,
},
traditional: true
...
Suppose my_list = [ 1, 2, 3 ], this results a query string / POST data
my_list=1&my_list=2&my_list=3
Without the traditional flag, the result would be
my_list[]=1&my_list[]=2&my_list[]=3
Which of course works, but in TurboGears you need to access it as my_list[].
On the other hand, I am not sure if the TG keyword argument passing work with multiple values; if you get a single value in kw, you can use request.getall('foo') to return all the foo keys as a list (possibly an empty list).

JSON Get Items by Value

What is the most efficient way to filter an JavaScript array of objects based on a key-value?
For example: I'd like to select items by color in the following array:
[{Id:1, color:"blue"},{Id:2, color:"green"},{Id:3, color:"blue"},{Id:4, color:"red"}]
There's an easy syntax for selecting items by property in languages like CSS or xslt, but I can't find an equivalent for JSON.
You can't filter JSON strings directly -- with ease, at least -- without first parsing them into JavaScript objects:
var collection = JSON.parse(jsonString);
But note that JSON parsers are normally strict -- object keys must be strings (http://json.org):
[{ "Id": 1, "color": "blue" }, { "Id": 2, "color": "green" }, ...]
After that, you can use filter on the returned Array:
var filtered = collection.filter(function (item) {
return item.color === "blue";
});
console.log(filtered[0]); // [Object] :: { Id: 1, color: "blue" }
To support older browsers, include json2.js for JSON.parse along with the "Compatibility" code offered by MDN for filter (or use the ES5-shim for a collection of such definitions).
JSON is not a language. I assume you mean javascript. And you will have to write it yourself there is no built in way.

Categories

Resources