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"]]
Related
I want to transform the given array into result array:
given = [{
"foo_v1_4" => [{
"derivate_version" => 0,
"layers" => {
"tlayer" => {
"baz" => {
"three" => 0.65
},
"bazbar" => {
"three" => 0.65
}
}
}
}]
}]
# the value of key :one is first hash key (foo_v1_4) plus underscore (_) plus derivate_version (0)
result = [{
one: 'foo_v1_4_0',
tlayer: 'baz',
three: '0.6'
},
{
one: 'foo_v1_4_0',
tlayer: 'bazbar',
three: '0.6'
}
]
What I tried:
given.each do |el |
el.each do |derivat |
derivat.each do |d |
d.each do |layer |
layer.each do |l |
derivat = "#{d}_#{l['derivate_version']}"
puts derivat
end
end
end
end
end
I'm struggling at iterating through "layers" hash, the amount of elements in layers is equal to the amount of elements in result array.
It helps to format the objects so we can better see their structures:
given = [
{
"foo_v1_4" => [
{ "derivate_version" => 0,
"layers" => {
"tlayer" => {
"baz" => { "three" => 0.65 },
"bazbar" => { "three" => 0.65 }
}
}
}
]
}
]
result = [
{
one: 'foo_v1_4_0',
tlayer: 'baz',
three: '0.6'
},
{
one: 'foo_v1_4_0',
tlayer: 'bazbar',
three: '0.6'
}
]
We can begin by writing the structure of result:
result = [
{
one:
tlayer:
three:
},
{
one:
tlayer:
three:
}
]
We see that
given = [ { "foo_v1_4" => <array> } ]
The values of the keys :one in the hash result[0] is therefore the first key of the first element of given:
one_val = given[0].keys[0]
#=> "foo_v1_4"
result = [
{
one: one_val
tlayer:
three:
},
{
one: one_val
tlayer:
three:
}
]
All the remaining objects of interest are contained in the hash
h = given[0]["foo_v1_4"][0]["layers"]["layer"]
#=> {
# "baz"=>{ "three"=>0.65 },
# "bazbar"=>{ "three"=>0.65 }
# }
so it is convenient to define it. We see that:
h.keys[0]
#=> "baz"
h.keys[1]
#=> "bazaar"
h["bazbar"]["three"]
#=> 0.65
Note that it generally is not good practice to assume that hash keys are ordered in a particular way.
We may now complete the construction of result,
v = h["bazbar"]["three"].truncate(1)
#=> 0.6
result = [
{
one: one_val,
tlayer: h.keys[0],
three: v
},
{ one: one_val,
tlayer: h.keys[1],
three: v
}
]
#=> [
# { :one=>"foo_v1_4", :tlayer=>"baz", :three=>0.6 },
# { :one=>"foo_v1_4", :tlayer=>"bazbar", :three=>0.6 }
# ]
The creation of the temporary objects one_val, h, and v improves time- and space-efficiency, makes the calculations easier to test and improves the readability of the code.
Try the below:
result = []
given.each do |level1|
level1.each do |key, derivate_versions|
derivate_versions.each do |layers|
# iterate over the elements under tlayer
layers.dig('layers', 'tlayer').each do |tlayer_key, tlayer_value|
sub_result = {}
# key - foo_v1_4, layers['derivate_version'] - 0 => 'foo_v1_4_0'
sub_result[:one] = key + '_' + layers['derivate_version'].to_s
# talyer_key - baz, barbaz
sub_result[:tlayer] = tlayer_key
# talyer_value - { "three" => 0.65 }
sub_result[:three] = tlayer_value['three']
result << sub_result
end
end
end
end
The value of result will be:
2.6.3 :084 > p result
[{:one=>"foo_v1_4_0", :tlayer=>"baz", :three=>0.65}, {:one=>"foo_v1_4_0", :tlayer=>"bazbar", :three=>0.65}]
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 }
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"]
# ]}]]
I have the following array where I want to select each of the keys:
names = [
{"Ánias"=>{:gender=>"male", :nationality=>"faroese"}},
{"Annfinnur"=>{:gender=>"male", :nationality=>"faroese"}},
{"Ansgar"=>{:gender=>"male", :nationality=>"faroese"}}
]
How would I go about selecting all the names ("Ánias", "Annfinnur", "Ansgar")?
Just do
names = [
{"Ánias"=>{:gender=>"male", :nationality=>"faroese"}},
{"Annfinnur"=>{:gender=>"male", :nationality=>"faroese"}},
{"Ansgar"=>{:gender=>"male", :nationality=>"faroese"}}
]
names.map { |h| h.keys.first }
# => ["Ánias", "Annfinnur", "Ansgar"]
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.