how to cast a json array into json object - xquery

let $jsonobject :=
{
"a": "val1 as value1",
"b": "val2 as value2, val3 as value3"
}
let $jsonarray :=
{
"a": "val1",
"b": [
"a1",
"a"
]
}
how are the above two different from each other? How can we convert the json array into json object using xquery?

Often, it is easiest to create a mutable map and array data structure and then convert to an immutable JSON object-node() or array-node(), as in:
let $jsonobject := xdmp:to-json(
map:entry("a", "val1 as value1")
=>map:with("b", "val2 as value2, val3 as value3")
)
let $jsonarray := xdmp:to-json(
map:entry("a", "val1")
=>map:with("b", json:to-array(("a1", "a")))
)
In most cases, immutable JSON nodes are needed only when inserting into the database. If the mutable map and array structure is sufficient, just omit the call to xdmp:to-json().
Hoping that helps,

Related

Why am I getting double reference to type when iterating over vector of references? [duplicate]

This question already has answers here:
What is an idiomatic way to collect an iterator of &T into a collection of Ts?
(2 answers)
Closed 12 months ago.
Consider following minimum reproducible. I have a vector of objects and I have a hashmap where each value is a vector of references to objects from the objects vector.
I then get a value from HashMap (which is a reference to vector of references) and I want to filter it so I get vector of references to objects. However, when I do iter-filter-collect, compiler claims that I am iterating over &&O (instead of &O I expect) and errors out.
I can "fix" that error by uncommenting the map function which dereferences iterated objects, however I don't think that is the correct thing to do here.
use std::collections::HashMap;
struct O {
a: i32,
b: i32,
}
fn main() {
let mut objects = vec![
O { a: 1, b: 0 },
O { a: 2, b: 0 },
O { a: 3, b: 0 },
O { a: 4, b: 1 },
];
let mut b_to_o: HashMap<i32, Vec<&O>> = HashMap::new();
for o in &objects {
b_to_o.entry(o.b).or_insert(Vec::new()).push(&o);
}
let b_zero: &Vec<&O> = b_to_o.get(&0).unwrap();
let b_zero_a_odd: Vec<&O> = b_zero
.iter()
.filter(|o| o.a % 2 == 0)
//.map(|o| *o)
.collect::<Vec<&O>>();
}
NOTE: Vector of objects doesn't have to be mut in this example, but it has to be in the code I am reproducing.
You have a Vec<&T> and iter yields &Output, where Output is the inner type of the Vec, in this case &T, you you get: &Output => &&T.
There is nothing wrong on dereferencing the double reference, you can use map, or you can use filter_map as a single step (notice the pattern mathing in the closure parameter to dereference directly |&o|):
let b_zero_a_odd: Vec<&O> = b_zero
.iter()
.filter_map(|&o| if o.a % 2 == 0 { Some(o) } else { None })
.collect::<Vec<&O>>();
Playground

Kotlin standard approach of making new map from an immutable map and additional key-value

Is there a standard way in Kotlin to associate a new key-value pair with an immutable map?
associate(mapOf("A" to 1, "B" to 2), "C", 3); // => {A=1, B=2, C=3}
Thinking about something similar to accos function in Clojure.
(assoc {:key1 "value1" :key2 "value2"} :key3 "value3")
;;=> { :key1 "value1", :key2 "value2", :key3 "value3"}
It is obvious how to make it directly copying entries into a new map, but I believe there is more optimal approach way implemented in the Kotlin standard library. Could you give an example of making this idiomatically?
This is done using the plus operator.
val map1 = mapOf("A" to 1, "B" to 2)
val map2 = map1 + ("C" to 3)
// or for a read-write variable/property:
var map = mapOf("A" to 1, "B" to 2)
map += "C" to 3
If you want to add more than one item at once, you can put any collection or array of pairs after the plus sign:
val map1 = mapOf("A" to 1, "B" to 2)
val map2 = map1 + arrayOf("C" to 3, "D" to 4)
Note that the correct terminology for a Map is “read-only” map, not “immutable” map. A Map is often a MutableMap under the hood that has been cast to a read-only Map, so it is not actually immutable. There is a common pattern in Kotlin of a class exposing access to a mutable collection through a property that upcasts it to a read-only implementation but continues to mutate that reference for the outside classes to observe changes.

F# how to specify when creating union case value what value to set to which field?

I have a dictionary where the key is the name of the field, and the value is this field value. Is it possible to somehow explicitly indicate to which field what value to assign using this dictionary? Or is the only way to stick to the sequence of field declarations when passing the second argument to the FSharpValue.MakeUnion?
Two different approaches:
If the names match exactly, and you're willing to "stick to the sequence of field declarations when passing the second argument to the FSharpValue.MakeUnion", you can do this:
open FSharp.Reflection
let instantiate (unionCase : UnionCaseInfo) (dict : Map<_, _>) =
let args =
unionCase.GetFields()
|> Array.map (fun field ->
dict.[field.Name] :> obj)
FSharpValue.MakeUnion(unionCase, args)
Example usage:
type MyType = UnionCase of a : int * b : int * c : int
let unionCase =
FSharpType.GetUnionCases(typeof<MyType>)
|> Array.exactlyOne
let dict =
Map [
"a", 1
"b", 2
"c", 3
]
instantiate unionCase dict
:?> MyType
|> printfn "%A"
Output is:
UnionCase (1, 2, 3)
If you want to avoid reflection, you can assign to the fields in any order you want, like this:
UnionCase (
c = dict.["c"],
b = dict.["b"],
a = dict.["a"])

Is it possible to expand a collection to multiple parameters of a function

I have a Vec which has following elements:
let v = vec!(["ABC", "DEFG", "HIJKLMN"],
["foobar", "bar", "foo"],
["foobar2", "bar2", "foo2"])
I am using a macro table! from library prettytable-rs which accepts parameters as follows:
let table = table!(["ABC", "DEFG", "HIJKLMN"],
["foobar", "bar", "foo"],
["foobar2", "bar2", "foo2"]);
table.printstd();
Basically I want to explode the Vec v and pass its elements as multiple parameters to macro table! or any function/method for that matter. Is it possible to do so?
No. Macros work on the syntax trees, and cannot deconstruct an existing variable like this.
However, using the table! macro isn't the only way to construct a prettytable::Table. If you look at the doc, you will notice that there is an implementation of:
impl<T, A, B> From<T> for Table where
B: ToString,
A: IntoIterator<Item = B>,
T: IntoIterator<Item = A>,
which means that you can construct a table from anything that is a doubly iterable, yielding something that implements ToString.
This allows to construct the table like this:
#[macro_use]
extern crate prettytable;
use prettytable::Table;
fn main() {
let v = vec![
["ABC", "DEFG", "HIJKLMN"],
["foobar", "bar", "foo"],
["foobar2", "bar2", "foo2"],
];
let table = prettytable::Table::from(v.iter());
// Print the table to stdout
table.printstd();
}

Idiomatically parsing a whitespace-separated string into a Vec of tuples of differing types

I have a struct EnclosingObject which contains a field of a Vec of tuples. I want to implement FromStr for this struct in a way that an EnclosingObject can be parsed from a string with the following structure: <number of tuples> <tuple1 str1> <tuple1 str2> <tuple1 i32> <tuple2 str1> <tuple2 str2> ...
This is what I have come up with so far (ignoring the case of an invalid number of tuples):
use std::str::FromStr;
use std::num::ParseIntError;
#[derive(Debug)]
struct EnclosingObject{
tuples: Vec<(String, String, i32)>,
}
impl FromStr for EnclosingObject {
type Err = ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let elems_vec = s.split_whitespace().collect::<Vec<_>>();
let mut elems = elems_vec.as_slice();
let num_tuples = elems[0].parse::<usize>()?;
elems = &elems[1..];
let mut tuples = Vec::with_capacity(num_tuples);
for chunk in elems.chunks(3).take(num_tuples){
tuples.push((chunk[0].into(),
chunk[1].into(),
chunk[2].parse::<i32>()?));
}
Ok(EnclosingObject{
tuples : tuples
})
}
}
fn main(){
println!("{:?}", EnclosingObject::from_str("3 a b 42 c d 32 e f 50"));
}
(playground)
As expected, for a valid string it prints out:
Ok(EnclosingObject { tuples: [("a", "b", 42), ("c", "d", 32), ("e", "f", 50)] })
and for an invalid string e.g. "3 a b x c d 32 e f 50":
Err(ParseIntError { kind: InvalidDigit })
Can I parse this Vec of tuples in a more elegant/idiomatic way, such as by using iterators?
I tried a combination of map and collect, but the problem with this is the error handling:
let tuples = elems
.chunks(3)
.take(num_tuples)
.map(|chunk| (chunk[0].into(),
chunk[1].into(),
chunk[2].parse::<i32>()?))
.collect();
The questionmark-operator seems not to work in this context (within the tuple). So I transformed it a bit:
let tuples = try!(elems
.chunks(3)
.take(num_tuples)
.map(|chunk| {
let integer = chunk[2].parse::<i32>()?;
Ok((chunk[0].into(),
chunk[1].into(),
integer))})
.collect());
... which works, but again appears a bit cumbersome.
The questionmark-operator seems not to work in this context (within the tuple).
The problem is that ? returns an Err in case of failure and you weren't returning an Ok in case of success. The operator works just fine if you do that. Beyond that, you can avoid the extraneous allocation of the Vec by operating on the iterator from splitting on whitespace:
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut elems = s.split_whitespace();
let num_tuples = elems.next().expect("error handling: count missing").parse()?;
let tuples: Vec<_> = elems
.by_ref()
.tuples()
.map(|(a, b, c)| Ok((a.into(), b.into(), c.parse()?)))
.take(num_tuples)
.collect::<Result<_, _>>()?;
if tuples.len() != num_tuples { panic!("error handling: too few") }
if elems.next().is_some() { panic!("error handling: too many") }
Ok(EnclosingObject { tuples })
}
I've also used Itertools' tuples method which automatically groups an iterator into tuples and collected into a Result<Vec<_>, _>. I reduced the redundant tuples: tuples in the struct and added some placeholders for the remainder of the error handling. I removed the Vec::with_capacity because I trust that the size_hint set by take will be good enough. If you didn't trust it, you could still use with_capacity and then extend the vector with the iterator.

Resources