In JSON, how to create a basic identity of one of the value - json

I have no idea about JSON (nor YAML), so I would like to start with a very simple 'identity' operation: formed by a two-pair object, how can I return another JSON that makes the identity of the value of one of the two pairs?
For example, given {"a": a, "b":b}, how can I read that and return a JSON whose content is {"b'":b}? I only think I know how to represent the input JSON (and the output JSON), but I don't know how to relate them so that the input 'b' is also in the output.
I am looking for an "implementation" of this that is something like a function that receives a JSON and returns a JSON. I do not know if this can be done within JSON or we need a programming language and use a toJSON like.
Any help? Also, where can I learn similar very fundamental concepts of JSON?

Here is a JavaScript solution. You can try this out in your browser console.
let json = "{ \"a\": \"a\", \"b\": \"b\" }";
let obj = JSON.parse(json); // { a: 'a', b: 'b' }
let entries = Object.entries(obj); // [ ['a', 'a'], ['b', 'b'] ]
let secondEntry = entries[1]; // ['b', 'b']
let newObj = Object.fromEntries([secondEntry]); // { b: 'b' }
let newJson = JSON.stringify(newObj) // "{ \"b\": \"b\" }"

This should also work in Python:
#given a JSON and a position to copy,
#it (line by line) performs:
#(1) transforms it to a Python dictionary
#(2) takes its key
#(3) takes its value
#(4) creates the new key with '
#(5) creates a dictionary with (key':val)
#(6) translated the new dict to a JSON
#(7) returns the JSON
def take_secondValue(orig_JSON, pos):
to_Dict = json.loads(orig_JSON)
ident_key = list(to_Dict.keys())[pos]
ident_val = list(to_Dict.values())[pos]
new_key = ident_key+"'"
new_dict = {new_key : ident_val}
out_JSON = json.dumps(new_dict)
return out_JSON

Related

How do I make a for loop that scans through JSON in F#

Using F# I am trying to scan through a JSON file and compare its arrays against a single array of (randomly generated) numbers. The formatting for the json is:
{"1":[#,#,#,#,#],"2":[#,#,#,#,#],...}
etc for 121 entries. I'm currently trying Json.NET. My problems are:
How can I import a local file with Json.NET?
How would I set about making a simple call of the json key that'd return it's array value that's fit to run it through a for loop?
Here is my code of how far I've gotten:
open System
open System.IO
open Newtonsoft.Json
(*open FSharp.Data
type Provider = JsonProvider<"powernum.json">
let numbers = Provider.Load("powernum.json")
//numbers.``1`` gets me the array but can't scan through all the IDs with an iterating for loop
(*
if numbers.``3`` = [|29;30;41;48;64|] then
printfn "True"
else printfn "False"
*)
(*numbers.JsonValue.Item "1"
let test (a: int) = string a
let testPile =
for i = 1 to 10 do
let goNum = numbers.JsonValue.Item (test i)
Console.Write goNum
Console.WriteLine ""
testPile // This works but is not usable for data comparison with an F# Array
*)
*)
let r = new StreamReader("\PATH\powernum.json")
let (json: string) = r.ReadToEnd();
let conv = JsonConvert.DeserializeObject<> (json)
Console.WriteLine("{0}",conv)//where I'm stuck with Json.NET
[<EntryPoint>]
let main argv =
let rnd = Random()
let numberGen = Set.empty.Add(rnd.Next(1,69)).Add(rnd.Next(1,69)).Add(rnd.Next(1,69)).Add(rnd.Next(1,69)).Add(rnd.Next(1,69)) |>Set.toArray |>Array.sort
Console.ReadKey() |> ignore
0// return an integer exit code
Jsontocsharp.com renders invalid.
I've tried using F# Data but from what I've found it's impossible to make an iterating loop because I have to pull up the "key" with accents encapsulating the number to read it as an int like this numbers.``1``.It doesn't take variables. Tried another method while still using F# Data but it only works as a string that errors when I try to convert it.
For comparison this is the version I prototyped in python:
import random
import json
with open('/PATH/powernum.json') as pnumbers:
data = json.load(pnumbers)
#makes an array with the range of numbers
Valid_numbers =[]
for x in range(69):
Valid_numbers.append(x+1)
generated = []
def pulledNumber():
generated[:]=[]
#adds numbers to the array from 0-4
while len(generated) !=5:
#takes a random number from the range of numbers
generate_number = random.choice(Valid_numbers)
#check if the two arrays have the same values
if generate_number not in generated:
#add to the array if values don't match
generated.append(generate_number)
generated.sort()
return generated
pulledNumber()
for x, y in data.items():
if generated not in y:
print("Id: %s passed" % x)
else:
print("Id: %s failed" % x)
pulledNumber()
break
print (pulledNumber())
f# is a statically typed language - we simply often don't notice because of its excellent type inferencing. But when deserializing from a JSON file, before writing any code, it is useful to determine whether the JSON has a fixed schema, and if so, create or choose an appropriate data model to which the JSON can be mapped automatically.
In your case, your JSON looks like:
{
"1": [29,30,41,48,64],
"2": [29,320,441,548,11]
// Additional items omitted
}
When you have here is a root object with variable property names whose values are always an array of integers. As explained in the Newtonsoft documentation Deserialize a Dictionary, such a JSON object can be deserialized to some IDictionary<string, T> for appropriate value type T. And as explained in Deserialize a Collection a JSON array can be deserialized to a collection of an appropriate item type.
In f# we use Map<'Key,'Value> to represent a dictionary, and lists to represent a materialized list of statically typed values. Thus your JSON corresponds to a
Map<string, int list>
Having determined an appropriate data model, introduce the following function to deserialize JSON from a file:
//https://www.newtonsoft.com/json/help/html/DeserializeWithJsonSerializerFromFile.htm
let jsonFromFile<'T>(fileName : string, settings : JsonSerializerSettings) =
use streamReader = new StreamReader(fileName)
use jsonReader = new JsonTextReader(streamReader)
let serializer = JsonSerializer.CreateDefault(settings)
serializer.Deserialize<'T>(jsonReader)
Now you can deserialize your JSON and filter the values for lists matching some
let fileName = "\PATH\powernum.json"
let requiredValues = [29;30;41;48;64] // Or whatever list of values you are looking for
let map = jsonFromFile<Map<string, int list>>(fileName, null)
let filteredMap =
map |> Map.toSeq
|> Seq.filter (fun (key, value) -> requiredValues = value)
|> Map.ofSeq
// Print results
filteredMap |> Map.iter (fun key value ->
printf "Key = %A has matching list of values = %A\n" key value)
Which prints out
Key = "1" has matching list of values = [29; 30; 41; 48; 64]
Notes:
Always be sure to dispose of disposable resources such as StreamReader after you are done with them. The use keyword ensures this happens automatically when the resource goes out of scope.
If you would prefer to search for an unordered set of values, you can use set instead of list:
let requiredValues = set [64;29;30;41;48] // Or whatever set of values you are looking for
let map = jsonFromFile<Map<string, Set<int>>>(fileName, null)
let filteredMap =
map |> Map.toSeq
|> Seq.filter (fun (key, value) -> requiredValues = value)
|> Map.ofSeq
As explained in Equality and Comparison Constraints in F# by Don Syme, both list and set support structural equality comparisons, which is why requiredValues = value checks that the collections have identical contents.
Demo fiddle #1 here for list and #2 here for set.

Getting the only key of a Map from JsonSlurper

I have JSON that needs to be processed using Groovy. I am pretty sure that the JSON has only one key, with this format:
{ rootKey: [...] }
Where rootKey stands for different values (e.g. "customers", "stores", etc.).
Let's say I used JsonSlurper:
def map = jsonSlurper.parseText(myjson)
How do I obtain that rootKey string?
You should be able to use keySet method to get the keys which is a list. Since, you mentioned only key, you can use the first element as shown below:
def jsonString = """{
"rootKey": []
}"""
def json = new groovy.json.JsonSlurper().parseText(jsonString)
println json.keySet()[0]

How to sort json data in groovy in alphabetic order?

I want to sort an json data which is like this
def json = []
for ( int i=10;i>1;i--){
if (i==10 || i==9 ){
json << [ name:"xyz",
id:i
]
}else
if (i==8 || i==7 ){
json << [ name:"abc",
id:i
]
}
}
// def jsondata = [success:true, rows:json]
def jsondata = [success:true, rows:json.sort(false) { it.name }]
print jsondata​
groovy.lang.MissingMethodException: No signature of method: java.util.ArrayList.sort() is applicable for argument types: (java.lang.Boolean, com.cs.AdminController$_closure15_closure83) values: [false, com.cs.controllers.AdminController$_closure15_closure83#3e020351]
Possible solutions: sort(), sort(java.util.Comparator), sort(groovy.lang.Closure), wait(), size(), size()
I want that data to be sorted alphabetic order ascending or descending
above one is working in a groovy console but not in my program , do i need to add something else like lib ?
Your output format seems to have no similarity to your code you posted
Also, your code you posted cannot just be run by someone trying to answer this question.
So this will be an educated guess...
Try:
def jsondata = [success:true, rows:json.sort(false) { it.name }, total:totalCount]
If you're using groovy from way back in the day for some unknown reason, then just drop the false, but beware as this will mutate your json list...
def jsondata = [success:true, rows:json.sort { it.name }, total:totalCount]

How do I deserialize a JSON array using the Play API

I have a string that is a Json array of two objects.
> val ss = """[ {"key1" :"value1"}, {"key2":"value2"}]"""
I want to use the Play Json libraries to deserialize it and create a map from the key values to the objects.
def deserializeJsonArray(ss:String):Map[String, JsValue] = ???
// Returns Map("value1" -> {"key1" :"value1"}, "value2" -> {"key2" :"value2"})
How do I write the deserializeJsonArray function? This seems like it should be easy, but I can't figure it out from either the Play documentation or the REPL.
I'm a bit rusty, so please forgive the mess. Perhaps another overflower can come in here and clean it up for me.
This solution assumes that the JSON is an array of objects, and each of the objects contains exactly one key-value pair. I would highly recommend spicing it up with some error handling and/or pattern matching to validate the parsed JSON string.
def deserializeJsonArray(ss: String): Map[String, JsValue] = {
val jsObjectSeq: Seq[JsObject] = Json.parse(ss).as[Seq[JsObject]]
val jsValueSeq: Seq[JsValue] = Json.parse(ss).as[Seq[JsValue]]
val keys: Seq[String] = jsObjectSeq.map(json => json.keys.head)
(keys zip jsValueSeq).toMap
}

JSON to Groovy with JsonSlurper and unknown "string"

I am writing a Grails/Groovy app and I have a JSON object with a "string" name (grommet and widget) inside the params member that can change. That is, next time it might be acme and zoom. Here is the JSON:
def jx = """{
"job": "42",
"params": {
"grommet": {"name": "x", "data": "y"},
"widget": { "name": "a", "data": "b"}
}
}"""
I am trying to figure out how to get the string grommet . Code so far:
def dalist = new JsonSlurper().parseText(jx)
println dalist.job // Gives: 42
println dalist.params // Gives: [grommet:[name:x, data:y], widget:[name:a, data:b]]
println dalist.params[0] // Gives: null
Any idea how to get the string grommet? Iama going to keep hitting my head against a wall.
The params key on the JSON object is associated with a JSON object, not an array, so you cannot access it by index. JsonSlurper maps JSON objects to Groovy Maps, so you can access params by its keys, which are strings, e.g. dalist.params.grommet, which will give you the map [name: 'x', data: 'y'].
To access the keys on the params you can do dalist.params.keySet(), which will give you the list ['grommet', 'widget']. If you are interested in just knowing params keys, that should do the trick. If you need to get the 'grommet' string for some reason, you can do it by accessing the first element on that list, i.e. dalist.params.keySet()[0], but i don't know why you would want to know that. And i'm not sure if it is guaranteed that the first key of that map will always be 'grommet', as JSON objects are unordered by the spec (from json.org: An object is an unordered set of name/value pairs), but, in turn, Groovy maps are ordered (the default implementation is LinkedHashMap)... so i would assume that the order is preserved when parsing JSON to the Groovy world, but i'd try not to rely on that particular behavior hehe.
It's Map instance, try:
def params = dalist.params.entrySet() as List // entrySet() returns Set, but it's easier to use it as a List
println params
println params.size()
println params[0]
println params[0].key
println params[0].value
This might help you.
import groovy.json.JsonSlurper;
def jx='{"job":"42","params":{"grommet":{"name":"x","data":"y"},"widget":{"name":"a","data":"b"}}}'
def dalist = new JsonSlurper().parseText( jx )
assert dalist.params.getClass().name == "java.util.HashMap";
assert dalist.params.size() == 2;
def keys = dalist.params.collect{ a, b -> a}; // returns "[grommet, widget]"
assert !!dalist.params.get( "grommet" ) == true