Comparing Deep Nested Array of Array of Hashes in Ruby - ruby

I have an array of array of hashes which can be nested any level deep.
array = [
[ ['a','2'], ['b','5'] ],
[ ['c','4'], ['d','5'] ],
[ ['e','6'], [f,7] ],
...]
In the first stage I need to compare each consecutive hash - keep one of the elements and discarding the other.
In the second step the selected element of hash 1 have to be compared to selected element of the hash 2. This process has to continue till i am left with just one hashed element.
How do i do this i Ruby ?
thanks a lot for answering

You can do this with ==:
array1 = [
[ ['a','2'], ['b','5'] ],
[ ['c','4'], ['d','5'] ],
[ ['e','6'], ['f',7] ]
]
array2 = [
[ ['a','2'], ['b','5'] ],
[ ['c','4'], ['d','5'] ],
[ ['e','6'], ['f',7] ]
]
array3 = [
[ ['not','equal'] ]
]
array1 == array2
# => true
array2 == array3
# => false
See Array#== for specifics.

Related

ruby fill elements of an array into a set of nested arrays and remove duplicates

I have the arrays months and monthly_doc_count_for_topic.
months = ["2019-01-01", "2019-02-01", "2019-03-01", "2019-04-01"]
monthly_doc_count_for_topic = [
["foo","2019-02-01: 186904","2019-03-01: 196961"],
["bar","2019-01-01: 8876","2019-04-01: 8694"]
]
goal = [
["foo","2019-02-01: 186904","2019-03-01: 196961","2019-01-01","2019-02-01","2019-03-01","2019-04-01"],
["bar","2019-01-01: 8876","2019-04-01: 8694","2019-01-01","2019-02-01","2019-03-01","2019-04-01"]
]
I'd like to fill in element of the array months into arrays inside monthly_doc_count_for_topic so it looks like array goal.
My attempt:
monthly_doc_count_for_topic.map do |topic_set|
months.each { |month| topic_set << month }
end
But I'm getting:
=> [
[0] [
[0] "2019-01-01",
[1] "2019-02-01",
[2] "2019-03-01",
[3] "2019-04-01"
],
[1] [
[0] "2019-01-01",
[1] "2019-02-01",
[2] "2019-03-01",
[3] "2019-04-01"
]
]
it's not appending the values from monthly_doc_count_for_topic instead replacing it with elements from array months. How can I modify my code to achieve the output like array goal? Thank you very much!
In your attempt replace
monthly_doc_count_for_topic.map
with
monthly_doc_count_for_topic.each
and it works perfectly fine:
goal = monthly_doc_count_for_topic.each do |topic_set|
months.each { |month| topic_set << month }
end
But I'd prefer CarySwoveland's solution in the comment, it's less verbose:
monthly_doc_count_for_topic.map { |topic_set| topic_set + months }

Using .sort_by to sort a nested array

I have a nested array that I want to sort by a specific object, some advice would be very much appreciated.
In this example I'd like the output to return sorted by the dates that are nested.
arr = [
[
{
"log"=>[
[
"2016-09-03T00:00:00-03:00",
],
[
"2016-09-01T00:00:00-03:00",
],
[
"2016-09-02T00:00:00-03:00",
]
]
}
]
]
arr = [
[
{
"log"=>[
["2016-09-03T00:00:00-03:00"],
["2016-09-01T00:00:00-03:00"],
["2016-09-02T00:00:00-03:00"]
]
}
]
]
To return a sorted array and not mutate arr:
[[{ "log"=>arr[0][0]["log"].sort_by(&:first) }]]
#=> [[{"log"=>[
# ["2016-09-01T00:00:00-03:00"],
# ["2016-09-02T00:00:00-03:00"],
# ["2016-09-03T00:00:00-03:00"]
# ]}]]
To sort in place:
arr[0][0]["log"] = arr[0][0]["log"].sort_by(&:first)
#=> [["2016-09-01T00:00:00-03:00"],
# ["2016-09-02T00:00:00-03:00"],
# ["2016-09-03T00:00:00-03:00"]]
arr
#=> [[{"log"=>[
# ["2016-09-01T00:00:00-03:00"],
# ["2016-09-02T00:00:00-03:00"],
# ["2016-09-03T00:00:00-03:00"]
# ]}]]

Ruby collection of strings as a parameter

I have a players() method that returns all players names.
I want to use this, as a parameter to twitter streaming, like this:
#client.track(players) do |tweet|
The gem does not allow it, so I have to do this:
#client.track('player1', 'player2', 'player3') do |tweet|
But that's terrible, since I have so many players.
Is that a way to parse my array into that list of strings?
I think what you're looking for is *, the "splat" operator:
players = [ "player1", "player2", "player3" ]
#client.track( *players )
# ...is equivalent to...
#client.track( "player1", "player2", "player3" )
Putting a splat before any object that responds to to_ary (like an Array, Hash, and most other Enumerables) will transform its items into an argument list. It's very handy and you'll see it a lot as you explore more Ruby code. Here's another example:
a = [ 3, 4 ]
[ 1, 2 ].push( a ) # no splat
# => [ 1, 2, [ 3, 4 ] ]
[ 1, 2 ].push( *a ) # splat!
# => [ 1, 2, 3, 4 ]
You can use it directly on objects, too—not just variables:
[ 1, 2, *[ 3, 4 ] ]
# => [ 1, 2, 3, 4 ]

Using transpose with arrays in Ruby?

I have the following:
table(
[
[
"UnitID",
"First Name",
"Last Name",
"NPS Score",
"Comments",
"emotion",
"polarity"
],
*[
invite_unitid_arr,
invite_name_arr,
invite_lastname_arr,
nps_score_integers,
comment_arr,
SadPanda.emotion(comment_arr),
SadPanda.polarity(comment_arr)
].transpose
]
)
However, SadPanda.emotion(comment_arr) and SadPanda.polarity(comment_arr) return:
undefined method 'gsub!' for #<Array:0x007f8f9b0d40a8>
How can I transpose the array but also use SadPanda.emotion() on each string value within the array?
EDIT:
To be clear, this is what I want as an end result:
[
invite_unitid_arr[0],
invite_name_arr[0],
invite_lastname_arr[0],
nps_score_integers[0],
comment_arr[0],
SadPanda.emotion(comment_arr[0]),
SadPanda.polarity(comment_arr[0])
],
[
invite_unitid_arr[1],
invite_name_arr[1],
invite_lastname_arr[1],
nps_score_integers[1],
comment_arr[1],
SadPanda.emotion(comment_arr[1]),
SadPanda.polarity(comment_arr[1])
]
Etc. etc. The .transpose method does exactly what I need it to do for all values in the array, but I don't know how to pass in comment_arr[0] on the .emotion and .polarity methods and increment that value each time the array is transposed.
To solve the issue:
new_comment_array_emotion = []
new_comment_array_polarity = []
comment_arr.each do |x|
new_comment_array_emotion << SadPanda.emotion(x)
new_comment_array_polarity << SadPanda.polarity(x)
end
table(
[
[
"UnitID",
"First Name",
"Last Name",
"NPS Score",
"Comments",
"emotion",
"polarity"
],
*[
invite_unitid_arr,
invite_name_arr,
invite_lastname_arr,
nps_score_integers,
comment_arr,
new_comment_array_emotion,
new_comment_array_polarity
].transpose
]
)
Feel free to propose a cleaner way of doing this within Ruby.

Include one array inside another complex array using ruby

I have the following arrays:
array = [ [link_text1, link1],[link_text2, link2], ... ]
array = [ [views1],[views2], ... ]
How can I can combine them, so I get this array:
[ [link_text1, link1, views1], [link_text2, link2, views2], ... ]
The same as robinst, but a little shorter
a1 = [ ["link_text1", "link1"],["link_text2", "link2"] ]
a2 = [ ["views1"],["views2"] ]
a1.zip(a2).map(&:flatten)
Try a combination of zip and flatten:
a1 = [ ["link_text1", "link1"],["link_text2", "link2"] ]
a2 = [ ["views1"],["views2"] ]
zipped = a1.zip(a2)
array_final = zipped.collect { |a| a.flatten }
#=> [["link_text1", "link1", "views1"], ["link_text2", "link2", "views2"]]

Resources