Wrap array in an array in JSONata - jsonata

Lets say I have a data structure that looks like this:
{ a: [ 1, 2, 3] }
I want to return 'a' wrapped in an array:
[ [ 1, 2, 3] ]
Is there any way to do this in JSONata?
Intuitively you would try [a], which you would expect to return the array as [[1,2,3]], but this returns [1,2,3], because of array singleton equivalence in JSONata.

You can try the below query
[[a]] - wrapping a within 2 set of square brackets
Since 'a' returns
1, 2, 3
[[a]] returns
[[1,2,3]]

Related

Why does uniq return original value of array after map in Ruby?

I tried the following code:
numbers = [1,2,2,3,4]
numbers.map.uniq {|number| number < 2 }
My understanding is that the return value of map is passed to uniq. I expected:
[true, false]
Instead, I received:
[1, 2]
It seems that uniq maintains a reference to the original array.
Could someone provide insight into this behaviour?
Array#uniq accepts a block, defining the condition on what should be treated uniq.
main > numbers = [1,2,2,3,4].map
#⇒ #<Enumerator: ...>
main > numbers.uniq
#⇒ [1, 2, 3, 4]
# effectively the same as
main > numbers.to_a.uniq
#⇒ [1, 2, 3, 4]
main > numbers.uniq { |number| number.odd? }
#⇒ [1, 2]
The latter returns one odd and one non-odd (even) element. In your case it returns 1 element that is less than 2 and one element that is greater or equal to two.
Note, that map enumerator is effectively there:
numbers.each &Math.method(:sqrt)
#⇒ [1.0, 1.4142135623730951, 1.4142135623730951,
# 1.7320508075688772, 2.0]
You're not actually doing anything with the map call, your function is roughly equivalent to this:
[1,2,2,3,4].uniq {|number| p number < 2 }
Methods like map return an Enumerable type, and you are then calling uniq on that Enumerable. From the Ruby docs:
If no block is given, an Enumerator is returned instead.
Effectively your map is a no-op.
I think you're also misunderstanding the uniq method. Uniq is going to filter out any elements from an array that aren't unique (eg: [1, 1, 2, 3, 3, 4, 5].uniq == [1, 2, 3, 4, 5]), not return whether the element is unique (true or false) in the array.
numbers.uniq.map { |number| number < 2 }
uniq method
uniq → new_ary click to toggle source uniq {|item| ...} → new_ary
Returns a new array by removing duplicate values in self.
If a block is given, it will use the return value of the block for
comparison.
It compares values using their hash and eql? methods for efficiency.
self is traversed in order, and the first occurrence is kept.
a = [ "a", "a", "b", "b", "c" ]
a.uniq # => ["a", "b", "c"]
b = [["student","sam"], ["student","george"], ["teacher","matz"]]
b.uniq {|s| s.first} # => [["student", "sam"], ["teacher", "matz"]]
You can read more about uniq method here.

why ruby inject method is not returning the sum inside a method

I was practicing ruby inject method and found one strange output:
def adding(*num)
res = num.inject{|sum,n| sum + n}
puts "sum:::::::::::::::::::#{res.inspect}"
puts "sum:::::::::::::::::::#{res.class}"
end
adding ([1,2,3,4,5])
Output:
sum:::::::::::::::::::[1, 2, 3, 4, 5]
sum:::::::::::::::::::Array
While when we do:
[1,2,3,4,5].inject{|sum,n| sum + n}
Output:
15
Why this strange output? In method call, adding([1,2,3,4,5]), it should also return 15.
What is the reason for this strange output?
num is not what you think it is.
def adding(*num)
num # => [[1, 2, 3, 4, 5]]
end
adding([1,2,3,4,5])
Either don't do the splat
def adding(num)
or pass numbers separately
adding(1, 2, 3, 4, 5)
To make a method like this that acceps either an array or an in-line list of numbers:
def adding(*num)
num.flatten.inject { |sum,n| sum + n }
end
The *num notation means that arguments are put into an array even if they're already an array, leading to inadvertent nesting.
Now this will work when called either of these ways:
adding(1, 2, 3)
adding([ 1, 2, 3 ])
It will also handle crazy stuff like:
adding([ [ 1 ], [ [ 2 ], [ [ 3 ] ] ] ])
That's because flatten will crunch down and eliminate any nested structures.

Get single hash value inside array of hashes

I have an array of hashes:
array = [
{
a: 1,
b: 2,
c: [3]
},
{
a: 1,
b: 2,
c: [3, 4, 5]
},
]
and would like to target the value 3 inside the array value for the c: key in the first hash. I assume something would be added to array[0] to capture that specific value.
In the Hash, c: [3] is syntax sugar for :c => [3]. So, to access the value 3:
array[0][:c][0]
#=> 3

Move or shift array element to last postion by condition + ruby array

I need to shift an element to last position by condition.
For ex.
[1,2,3] and to put 1 in last in array, without executing unnecessary loops.
o/p [2,3,1] for the above condition array will be dynamic and put particular element on last by condition.
I tried like this:
sd = [1,2,3]
sd.map{|d| sd.last(d) if d ==1 }
but the output is [[3], nil, nil]
We have Array#rotate method :-
[3] pry(main)> a = [1,2,3]
=> [1, 2, 3]
[4] pry(main)> a.rotate(1)
=> [2, 3, 1]
[5] pry(main)> a.rotate(2)
=> [3, 1, 2]
In your case, you should pass 1 as argument to the method #rotate. But 1 is default argument to the #rotate method, so you can omit it too. bang version of #rotate also exist.

Ruby Method similar to Haskells cycle

Is there a Ruby method similar to Haskell's cycle? Haskell's cycle takes a list and returns that list infinitely appended to itself. It's commonly used with take which grabs a certain number of elements off the top of an array. Is there a Ruby method that takes an array and returns the array appended to itself some n number of times?
Yes, it's called cycle. From the documentation:
Array.cycle
(from ruby core)
------------------------------------------------------------------------------
ary.cycle(n=nil) {|obj| block } -> nil
ary.cycle(n=nil) -> an_enumerator
------------------------------------------------------------------------------
Calls block for each element repeatedly n times or forever if none
or nil is given. If a non-positive number is given or the array is empty, does
nothing. Returns nil if the loop has finished without getting interrupted.
If no block is given, an enumerator is returned instead.
a = ["a", "b", "c"]
a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
a.cycle(2) {|x| puts x } # print, a, b, c, a, b, c.
Edit:
It seems like whats inside the block is basically a "Lambda", and as far as I know, I can't make a lambda concat each element onto an existing array.
b = [1, 2, 3]
z = []
b.cycle(2) { |i| z << i }
z # => [1, 2, 3, 1, 2, 3]
You can multiply an array by an integer using Array#*:
ary * int → new_ary
[...] Otherwise, returns a new array built by concatenating the int copies of self.
So you can do things like this:
>> [1, 2] * 3
=> [1, 2, 1, 2, 1, 2]

Resources