Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Longest common prefix and suffix of arrays

What is the best way to get the longest common prefix (sub-array that starts from index 0 of the original) and suffix (sub-array that ends with index -1 of the original) of two arrays? For example, given two arrays:

[:foo, 1, :foo, 0, nil, :bar, "baz", false]
[:foo, 1, :foo, 0, true, :bar, false]

the longest common prefix of these arrays is:

[:foo, 1, :foo, 0]

and the longest common suffix of these arrays is:

[false]

When the elements at index 0/-1 differ in the original arrays, then the common prefix/suffix should be an empty array.

like image 724
sawa Avatar asked Mar 18 '23 16:03

sawa


1 Answers

One possible solution:

a1 = [:foo, 1, 0, nil, :bar, "baz", false]
a2 = [:foo, 1, 0, true, :bar, false]

a1.zip(a2).take_while { |x, y| x == y }.map(&:first)
#=> [:foo, 1, 0]

Reversing the input arrays and the output array finds a common suffix:

a1.reverse.zip(a2.reverse).take_while { |x, y| x == y }.map(&:first).reverse
#=> [false]

Edge case: zip fills "argument" arrays with nil values:

a1 = [true, nil, nil]
a2 = [true]

a1.zip(a2).take_while { |x, y| x == y }.map(&:first)
#=> [true, nil, nil]

This can be avoided by truncating the initial array to the second array's length:

a1[0...a2.size].zip(a2).take_while { |x, y| x == y }.map(&:first)
like image 149
Stefan Avatar answered Mar 25 '23 21:03

Stefan