Merge and interleave two arrays in Ruby
You can do that with:
a.zip(s).flatten.compact
Unequally interleave two ruby arrays
a.each_slice(2).zip(b).flatten
#=> [1, 2, "a", 3, 4, "b", 5, 6, "c"]
Ruby, equally distribute elements and interleave/merge multiple arrays
I would use a sort to do this, based on element index postion, divided by size of array, plus some offset based on array id, to keep things consistent (if you don't need consistency, you could use a small random offset instead).
a = [:a,:b]
b = [:c]
c = [:d,:e,:f]
d = [:g:,:h,:i,:j]
def sort_pos array, id
(1..array.size).map { |i| (i - 0.5 + id/1000.0)/(array.size + 1e-6) }
end
# Combine all the arrays with their sort index, assigning ids to each array for consistency.
# Depending on how you receive these arrays, this structure can be built up programatically,
# as long as you add an array plus its sort index numbers at the same time
combined = (a + b + c + d).zip( sort_pos(a, 1) + sort_pos(b, 2) + sort_pos(c, 3) + sort_pos(d, 4) )
# Extract the values from the original arrays in their new order
combined.sort_by { |zipped| zipped[1] }.map { |zipped| zipped[0] }
=> [:g, :d, :a, :h, :e, :i, :b, :f, :j, :c]
There might be a cleaner way of doing this in Ruby . . . but I think the end result is what you are after - an "even" mix of multiple arrays.
If you only care about even-ness of mix from a statistical perspective (i.e. over time it is "fair"), you could just do this:
(a+b+c+d).shuffle
=> [:g, :b, :i, :c, :a, :h, :e, :j, :f, :d]
Ruby - Merge two arrays and remove values that have duplicate
You can do the following!
# Merging
c = a + b
=> [1, 2, 3, 4, 5, 2, 4, 6]
# Removing the value of other array
# (a & b) is getting the common element from these two arrays
c - (a & b)
=> [1, 3, 5, 6]
Dmitri's comment is also same though I came up with my idea independently.
How do I combine two arrays based on the index of their elements?
From the docs:
If the size of any argument is less than the size of the initial array, nil values are supplied.
So you do not need to worry about the case where the second array is shorter.
If the first array is shorter, pad it out with nil
to the length of the second array.
You can use compact
to remove the superfluous nil
s afterwards.
Case 1: a
is longer
a = [1, 2, 3, 4, 5]
b = [6, 7, 8]
a[b.count-1] ||= nil
a.zip(b).map(&:flatten).map(&:compact)
Result:
[[1, 6], [2, 7], [3, 8], [4], [5]]
Case 2: b
is longer
a = [1, 2, 3]
b = [4, 5, 6, 7, 8]
a[b.count-1] ||= nil
a.zip(b).map(&:flatten).map(&:compact)
Result:
[[1, 4], [2, 5], [3, 6], [7], [8]]
Variation with nil
included
a = [1, 2, 3, 4, 5]
b = [6, 7, 8]
a[b.count-1] ||= nil
b[a.count-1] ||= nil
a.zip(b).map(&:flatten) # [[1, 6], [2, 7], [3, 8], [4, nil], [5, nil]]
... and ...
a = [1, 2, 3]
b = [4, 5, 6, 7, 8]
a[b.count-1] ||= nil
b[a.count-1] ||= nil
a.zip(b).map(&:flatten) # [[1, 4], [2, 5], [3, 6], [nil, 7], [nil, 8]]
Notes
- If
a
orb
must not be modified, insert a.clone
somewhere to clone them beforehand. - The
.flatten
was taken from the OP's example; it flattens any arrays that take the role of the integers in the example. Keep or leave off as needed.
How to combine the sorting of two arrays into one?
To replicate the functionality you have (all authors, sorted, on top of all books, sorted,) you might use that nil
is falsey
in ruby.
author.concat(book).sort_by do |a|
if a.instance_of? Author
[1, a.name || -1, a.amount || -1]
else
[0, a.data || -1, a.price || -1]
end
end
Note that I put leading 1
for authors and 0
for books to preserve all the authors come before all the books.
Combine two arrays in Ruby?
I would transform the two arrays to lookup hashes. Then collect all the ids to iterate. Map the ids into the foo
and bar
values, then zip them together.
foo_lookup = foo.to_h { |id| [id, {id: id}] } # change `{id: id}` into `id` for the other output
bar_lookup = bar.to_h { |item| [item[:id], item] }
ids = foo_lookup.keys | bar_lookup.keys
res = ids.map(&foo_lookup).zip(ids.map(&bar_lookup))
#=> [[{:id=>1}, nil], [{:id=>2}, {:id=>2}], [nil, {:id=>4}]]
Related Topics
Difference Between Print and Puts
How to Install Therubyracer Gem on 10.10 Yosemite
Rails Paperclip How to Delete Attachment
Haml: Append Class If Condition Is True in Haml
Extract a Substring from a String in Ruby Using a Regular Expression
How to Get Rid of Non-Ascii Characters in Ruby
Confusion With Atomic Grouping - How It Differs from the Grouping in Regular Expression of Ruby
Converting String from Snake_Case to Camelcase in Ruby
When to Use Each Method of Launching a Subprocess in Ruby
Nomethoderror When Trying to Invoke Helper Method from Rails Controller
Rescue in Rbuf_Fill': Timeout::Error (Timeout::Error)
Rails Dot Instead of Slash in Url
Calculating the Number of Weeks in a Year with Ruby
Database.Yml &References Not Working
Test If Variable Matches Any of Several Strings W/O Long If-Elsif Chain, or Case-When