How to group identical elements in Ruby array
Here is how to do that in Ruby.
array.group_by{ |x| x }.values
How to group array elements by index?
You can use slice_after
to slice the array after each item whose index is in idx
:
idx = [1, 5, 7]
arr = %w[a b c d e f g h i j k]
arr.enum_for(:slice_after).with_index { |_, i| idx.include?(i) }.to_a
#=> [["a", "b"], ["c", "d", "e", "f"], ["g", "h"], ["i", "j", "k"]]
That enum_for
is (unfortunately) needed to chain slice_after
and with_index
.
Group by, array of arrays in ruby
Use following
some_array.group_by{|a| [a[0], a[1]]}
.map{|key, value| key + [value.map(&:last)]}
.flatten(1)
For multiple values in group by
2.3.1 :046 > some_array = [["FANUC CORP", "100048", 9], ["FANUC CORP", "100048", 26]
, ["FANUC CORP", "100048", 23], ["FANUC CORP", "100048", 111]
, ["FANUC CORP", "100049", 19],["FANUC CORP", "100049", 126],
["FANUC CORP", "100049", 123], ["FANUC CORP", "100049", 1111]]
=> [["FANUC CORP", "100048", 9], ["FANUC CORP", "100048", 26],
["FANUC CORP", "100048", 23], ["FANUC CORP", "100048", 111],
["FANUC CORP", "100049", 19], ["FANUC CORP", "100049", 126],
["FANUC CORP", "100049", 123], ["FANUC CORP", "100049", 1111]]
2.3.1 :047 > some_array.group_by{|a| [a[0], a[1]]}
.map{|key, value| key + [value.map(&:last)]}
.flatten(1)
=> ["FANUC CORP", "100048", [9, 26, 23, 111],
"FANUC CORP", "100049", [19, 126, 123, 1111]]
Ruby Array of Arrays Group and Count by Values
Using Enumerable#group_by
:
Array.group_by { |month, b| month }.map{ |month, xs|
[month,
xs.count {|_, b| !b}, # false
xs.count {|_, b| b}] # true
}
# => [["June", 3, 0], ["October", 1, 0]]
How can I group items in a ruby array based on characteristics of each element?
You can do that with a regex (followed by a messy bit to insert hyphens as required):
VOWELS = 'aeiou'
R = /
(?= # begin positive look-ahead
( # begin capture group 1
(?: # begin a non-capture group
[#{VOWELS}]+ # match one or more vowels
| # or
\A # match the beginning of the string
) # end non-capture group
[^#{VOWELS}]+ # match one or more consonants
(?: # begin a non-capture group
[#{VOWELS}]+ # match one or more vowels
| # or
\z # match end of string
) # end non-capture group
) # end capture group 1
) # end positive lookahead
/x # extended mode
def extract(str)
arr = str.scan(R).flatten
arr[0].insert(0, '-') unless VOWELS.include?(arr[0][0])
arr[-1] << '-' unless VOWELS.include?(arr[-1][-1])
arr
end
extract 'compare' #=> ["-co", "ompa", "are"]
extract 'compared' #=> ["-co", "ompa", "are", "ed-"]
extract 'avacados' #=> ["ava", "aca", "ado", "os-"]
extract 'zzz' #=> ["-zzz-"]
extract 'compaaared' #=> ["-co", "ompaaa", "aaare", "aare", "are", "ed-"]
Ruby group array of arrays to merge them into one single array based on unique key in arrays
I'm not certain that I understand the question but I expect you may be looking for the following.
arr = [
["ABC", "5A2", nil, "88474"],
["ABC", nil, "2", "88474"],
["ABC", nil, nil, "88474"],
["ABC", nil, nil, "88474"],
["Jack", "5A2", nil, "05195"],
["Jack", nil, "2", "05195"],
["Jack", nil, nil, "05195"],
["Jack", nil, nil, "05195"]
]
arr.each_with_object({}) do |a, h|
h.update(a.first=>a) { |_k, oa, na| oa.zip(na).map { |ov, nv| ov.nil? ? nv : ov } }
end.values
#=> [["ABC", "5A2", "2", "88474"], ["Jack", "5A2", "2", "05195"]]
This uses the form of Hash#update (a.k.a. merge!
) that employs the block
{ |_k, oa, na| oa.zip(na).map { |ov, nv| ov.nil? ? nv : ov } }
to determine the values of keys that are present in both the hash being built (h
) and the hash being merged ({ a.first=>a }
). See the doc for a description of the three block variables, _k
, oa
and na
.1
I can best explain how the calculations procede by salting the code with puts
statements and running it with an abbreviated array arr
.
arr = [
["ABC", "5A2", nil, "88474"],
["ABC", nil, "2", "88474"],
["Jack", "5A2", nil, "05195"],
["Jack", nil, "2", "05195"],
]
arr.each_with_object({}) do |a, h|
puts "\na = #{a}"
puts "h = #{h}"
puts "a.first=>a = #{a.first}=>#{a}"
h.update(a.first=>a) do |_k, oa, na|
puts "_k = #{_k}"
puts "oa = #{oa}"
puts "na = #{na}"
a = oa.zip(na)
puts "oa.zip(na) = #{a}"
a.map do |ov, nv|
puts " ov = #{ov}, nv = #{nv}"
puts " ov.nil? ? nv : ov = #{ov.nil? ? nv : ov}"
ov.nil? ? nv : ov
end
end
end.tap { |h| puts "h = #{h}" }.values
#=> [["ABC", "5A2", "2", "88474"], ["Jack", "5A2", "2", "05195"]]
The following is displayed.
a = ["ABC", "5A2", nil, "88474"]
h = {}
a.first=>a = ABC=>["ABC", "5A2", nil, "88474"]
(The block is not called here because h does not have a key "ABC")
a = ["ABC", nil, "2", "88474"]
h = {"ABC"=>["ABC", "5A2", nil, "88474"]}
a.first=>a = ABC=>["ABC", nil, "2", "88474"]
_k = ABC
oa = ["ABC", "5A2", nil, "88474"]
na = ["ABC", nil, "2", "88474"]
oa.zip(na) = [["ABC", "ABC"], ["5A2", nil], [nil, "2"], ["88474", "88474"]]
ov = ABC, nv = ABC
ov.nil? ? nv : ov = ABC
ov = 5A2, nv =
ov.nil? ? nv : ov = 5A2
ov = , nv = 2
ov.nil? ? nv : ov = 2
ov = 88474, nv = 88474
ov.nil? ? nv : ov = 88474
a = ["Jack", "5A2", nil, "05195"]
h = {"ABC"=>["ABC", "5A2", "2", "88474"]}
a.first=>a = Jack=>["Jack", "5A2", nil, "05195"]
(The block is not called here because h does not have a key "Jack")
a = ["Jack", nil, "2", "05195"]
h = {"ABC"=>["ABC", "5A2", "2", "88474"], "Jack"=>["Jack", "5A2", nil, "05195"]}
a.first=>a = Jack=>["Jack", nil, "2", "05195"]
_k = Jack
oa = ["Jack", "5A2", nil, "05195"]
na = ["Jack", nil, "2", "05195"]
oa.zip(na) = [["Jack", "Jack"], ["5A2", nil], [nil, "2"], ["05195", "05195"]]
ov = Jack, nv = Jack
ov.nil? ? nv : ov = Jack
ov = 5A2, nv =
ov.nil? ? nv : ov = 5A2
ov = , nv = 2
ov.nil? ? nv : ov = 2
ov = 05195, nv = 05195
ov.nil? ? nv : ov = 05195
h = {"ABC"=>["ABC", "5A2", "2", "88474"], "Jack"=>["Jack", "5A2", "2", "05195"]}
1. As is common practice, I began the name of the common key, _k
, with an underscore to signal to the reader that it is not used in the block calculation. Often you will see such a block variable represented by an underscore alone.
Grouping an array on the basis of its first element, without duplication in Ruby
You can do a secondary transform to it:
Hash[
array.group_by(&:first).collect do |key, values|
[ key, values.collect { |v| v[1] } ]
end
]
Alternatively just map out the logic directly:
array.each_with_object({ }) do |item, result|
(result[item[0]] ||= [ ]) << item[1]
end
Grouping subarrays in array by the same items Ruby
Next time it would be great if you will add some steps you was tried to do to get what you want, here is a fast solution:
> arr.group_by(&:shift).map(&:flatten)
#=> [["cat", "15", "20", "356"], ["dog", "17", "89", "336"], ["bird", "65", "545"]]
But, this will mutate original arr
@Md.FarhanMemon have good solution without mutate
Related Topics
Ruby, Value Bucketing, Beautify Code
Sum of All Amount If Charge Dates Are the Same in Stripe
Ruby Selenium Web Drive: How to Find Specific Element by Xpath Div Id and CSS Class
How to Merge Two Equally Sized Arrays into One Array with Sub-Arrays of Merged Values
How to Use Local or Instance Variable in Ruby Code in Coffeescript in Haml Template
Finding Parenthesis via Regular Expression
How to Check If a Specific Key Is Present in a Hash or Not
Convert Duration to Hours:Minutes:Seconds (Or Similar) in Rails 3 or Ruby
Ide Sublime2 How to Find Method Definition
I Want to Return a Single Result Using .Find() with Ruby on Rails
How to Capture Terminal Arrow Keys in Ruby
How to Translate Arabic/Persian Numbers to English Using Ruby
Writing a Pre-Push Hook in Git to Grep All Files for Regex Want to Reject Push If Regex Not Found
Ruby/Rails - Active Record Db Migration to MySQL - Timestamp Type
Rspec: How to Write Unit Test Case to Receive an Exception Which Is Getting Raised in Private Method
Delayedjob: "Job Failed to Load: Uninitialized Constant Syck::Syck"