require 'rspec/autorun'
describe '#cleanup_array' do
it 'removes duplicates' do
array_with_duplicates = [1, 2, 4, 4, 3, 5, 1]
expect(cleanup_array(array_with_duplicates)).to eq [1, 2, 3, 4, 5]
end
it 'removes nil values' do
array_with_nils = [1, 2, nil, 4, 3, 5, nil]
expect(cleanup_array(array_with_nils)).to eq [1, 2, 3, 4, 5]
end
it 'sorts array of integers' do
unsorted_int_arr = [3, 2, 4, 2]
expect(cleanup_array(unsorted_int_arr)).to eq [2, 3, 4]
end
it 'sorts array of strings' do
unsorted_str_arr = ["c\n", 'some new', 'omg', 'ca', 'omg']
expect(cleanup_array(unsorted_str_arr)).to eq ["c\n", 'ca', 'omg', 'some new']
end
it 'sorts integers like strings' do
arr = ['1a', '23', '13', 1, 16, 111]
expect(cleanup_array(arr)).to eq [1, 111, '13', 16, '1a', '23']
end
it 'sorts other objects as strings' do
time_obj = Time.now
arr = [5, 'awww', time_obj, '5', 'xd', '1a']
expect(cleanup_array(arr)).to eq ['1a', time_obj, 5, '5', 'awww', 'xd']
end
it 'sorts nested array as string' do
arr = [5, 'awww', 'xd', nil, ['lol', nil, 'fyi'], '1a', 3, '5', 'xd']
expect(cleanup_array(arr)).to eq ['1a', 3, 5, '5', 'awww', ['lol', nil, 'fyi'], 'xd']
end
it 'orders ascending by default' do
array_with_duplicates = [1, 2, 4, 4, 3, 5, 11]
expect(cleanup_array(array_with_duplicates)).to eq [1, 2, 3, 4, 5, 11]
end
it 'orders descending when passed a kwarg' do
array_with_duplicates = [1, 2, 4, 4, 3, 5, 11]
expect(cleanup_array(array_with_duplicates, order: :desc)).to eq [11, 5, 4, 3, 2, 1]
end
it 'allows to pass a custom sort lambda' do
array_with_duplicates = [[19, 2], [41, 8], [4, 17]]
expect(cleanup_array(array_with_duplicates, sort_key: ->(e) { e.max })).to eq [[4, 17], [19, 2], [41, 8]]
end
it 'is a part of Array class' do
expect(['a', '3', 1].cleanup_array(order: :desc, sort_key: lambda { |e|
e.to_i
})).to eq(['3', 1, 'a'])
end
end
# def cleanup_array(arr, opts = {})
# arr.compact! # Remove nil values
# arr.uniq! # Remove duplicates
# if opts[:sort_key]
# arr.sort_by!(&opts[:sort_key]) # Use custom sort key function if provided
# else
# all_ints = arr.all? {|el| Integer(el) rescue false}
# arr.sort_by! do |e|
# if all_ints
# e.to_i # Sort positive integers
# elsif e.is_a?(Array)
# e.map(&:to_s).join('_')
# else
# e.to_s # Sort other elements as strings
# end
# end
# end
# arr.reverse! if opts[:order] == :desc # Reverse only for explicit descending order
# arr
# end
def cleanup_array(arr, opts = {})
# Determine if all elements are integers and get the sort key function
arr = arr.compact.uniq
all_ints = arr.all? { |el| el.is_a?(Integer) rescue false }
sort_key = opts[:sort_key]
# Use a single sort_by call
arr.sort_by! do |e|
if sort_key
sort_key.call(e)
elsif all_ints
e.to_i
elsif e.is_a?(Array)
e.map(&:to_s).join('_')
else
e.to_s
end
end
# Reverse only for explicit descending order
arr.reverse! if opts[:order] == :desc
arr
end
class Array
def cleanup_array(opts = {})
sort_order = opts[:order] || :asc
sort_key = opts[:sort_key] || ->(e) { e.to_s }
sorted_array = compact.sort_by(&sort_key)
sorted_array.reverse! if sort_order == :desc
sorted_array
end
end
cmVxdWlyZSAncnNwZWMvYXV0b3J1bicKCmRlc2NyaWJlICcjY2xlYW51cF9hcnJheScgZG8KICBpdCAncmVtb3ZlcyBkdXBsaWNhdGVzJyBkbwogICAgYXJyYXlfd2l0aF9kdXBsaWNhdGVzID0gWzEsIDIsIDQsIDQsIDMsIDUsIDFdCiAgICBleHBlY3QoY2xlYW51cF9hcnJheShhcnJheV93aXRoX2R1cGxpY2F0ZXMpKS50byBlcSBbMSwgMiwgMywgNCwgNV0KICBlbmQKCiAgaXQgJ3JlbW92ZXMgbmlsIHZhbHVlcycgZG8KICAgIGFycmF5X3dpdGhfbmlscyA9IFsxLCAyLCBuaWwsIDQsIDMsIDUsIG5pbF0KICAgIGV4cGVjdChjbGVhbnVwX2FycmF5KGFycmF5X3dpdGhfbmlscykpLnRvIGVxIFsxLCAyLCAzLCA0LCA1XQogIGVuZAoKICBpdCAnc29ydHMgYXJyYXkgb2YgaW50ZWdlcnMnIGRvCiAgICB1bnNvcnRlZF9pbnRfYXJyID0gWzMsIDIsIDQsIDJdCiAgICBleHBlY3QoY2xlYW51cF9hcnJheSh1bnNvcnRlZF9pbnRfYXJyKSkudG8gZXEgWzIsIDMsIDRdCiAgZW5kCgogIGl0ICdzb3J0cyBhcnJheSBvZiBzdHJpbmdzJyBkbwogICAgdW5zb3J0ZWRfc3RyX2FyciA9IFsiY1xuIiwgJ3NvbWUgbmV3JywgJ29tZycsICdjYScsICdvbWcnXQogICAgZXhwZWN0KGNsZWFudXBfYXJyYXkodW5zb3J0ZWRfc3RyX2FycikpLnRvIGVxIFsiY1xuIiwgJ2NhJywgJ29tZycsICdzb21lIG5ldyddCiAgZW5kCgogIGl0ICdzb3J0cyBpbnRlZ2VycyBsaWtlIHN0cmluZ3MnIGRvCiAgICBhcnIgPSBbJzFhJywgJzIzJywgJzEzJywgMSwgMTYsIDExMV0KICAgIGV4cGVjdChjbGVhbnVwX2FycmF5KGFycikpLnRvIGVxIFsxLCAxMTEsICcxMycsIDE2LCAnMWEnLCAnMjMnXQogIGVuZAoKICBpdCAnc29ydHMgb3RoZXIgb2JqZWN0cyBhcyBzdHJpbmdzJyBkbwogICAgdGltZV9vYmogPSBUaW1lLm5vdwogICAgYXJyID0gWzUsICdhd3d3JywgdGltZV9vYmosICc1JywgJ3hkJywgJzFhJ10KICAgIGV4cGVjdChjbGVhbnVwX2FycmF5KGFycikpLnRvIGVxIFsnMWEnLCB0aW1lX29iaiwgNSwgJzUnLCAnYXd3dycsICd4ZCddCiAgZW5kCgogIGl0ICdzb3J0cyBuZXN0ZWQgYXJyYXkgYXMgc3RyaW5nJyBkbwogICAgYXJyID0gWzUsICdhd3d3JywgJ3hkJywgbmlsLCBbJ2xvbCcsIG5pbCwgJ2Z5aSddLCAnMWEnLCAzLCAnNScsICd4ZCddCiAgICBleHBlY3QoY2xlYW51cF9hcnJheShhcnIpKS50byBlcSBbJzFhJywgMywgNSwgJzUnLCAnYXd3dycsIFsnbG9sJywgbmlsLCAnZnlpJ10sICd4ZCddCiAgZW5kCgogIGl0ICdvcmRlcnMgYXNjZW5kaW5nIGJ5IGRlZmF1bHQnIGRvCiAgICBhcnJheV93aXRoX2R1cGxpY2F0ZXMgPSBbMSwgMiwgNCwgNCwgMywgNSwgMTFdCiAgICBleHBlY3QoY2xlYW51cF9hcnJheShhcnJheV93aXRoX2R1cGxpY2F0ZXMpKS50byBlcSBbMSwgMiwgMywgNCwgNSwgMTFdCiAgZW5kCgogIGl0ICdvcmRlcnMgZGVzY2VuZGluZyB3aGVuIHBhc3NlZCBhIGt3YXJnJyBkbwogICAgYXJyYXlfd2l0aF9kdXBsaWNhdGVzID0gWzEsIDIsIDQsIDQsIDMsIDUsIDExXQogICAgZXhwZWN0KGNsZWFudXBfYXJyYXkoYXJyYXlfd2l0aF9kdXBsaWNhdGVzLCBvcmRlcjogOmRlc2MpKS50byBlcSBbMTEsIDUsIDQsIDMsIDIsIDFdCiAgZW5kCgogIGl0ICdhbGxvd3MgdG8gcGFzcyBhIGN1c3RvbSBzb3J0IGxhbWJkYScgZG8KICAgIGFycmF5X3dpdGhfZHVwbGljYXRlcyA9IFtbMTksIDJdLCBbNDEsIDhdLCBbNCwgMTddXQogICAgZXhwZWN0KGNsZWFudXBfYXJyYXkoYXJyYXlfd2l0aF9kdXBsaWNhdGVzLCBzb3J0X2tleTogLT4oZSkgeyBlLm1heCB9KSkudG8gZXEgW1s0LCAxN10sIFsxOSwgMl0sIFs0MSwgOF1dCiAgZW5kCgogIGl0ICdpcyBhIHBhcnQgb2YgQXJyYXkgY2xhc3MnIGRvCiAgICBleHBlY3QoWydhJywgJzMnLCAxXS5jbGVhbnVwX2FycmF5KG9yZGVyOiA6ZGVzYywgc29ydF9rZXk6IGxhbWJkYSB7IHxlfAogICAgICBlLnRvX2kKICAgIH0pKS50byBlcShbJzMnLCAxLCAnYSddKQogIGVuZAplbmQKCiMgZGVmIGNsZWFudXBfYXJyYXkoYXJyLCBvcHRzID0ge30pCiMgICBhcnIuY29tcGFjdCEgIyBSZW1vdmUgbmlsIHZhbHVlcwojICAgYXJyLnVuaXEhICAgIyBSZW1vdmUgZHVwbGljYXRlcwoKIyAgIGlmIG9wdHNbOnNvcnRfa2V5XQojICAgICBhcnIuc29ydF9ieSEoJm9wdHNbOnNvcnRfa2V5XSkgIyBVc2UgY3VzdG9tIHNvcnQga2V5IGZ1bmN0aW9uIGlmIHByb3ZpZGVkCiMgICBlbHNlCiMgICAgIGFsbF9pbnRzID0gYXJyLmFsbD8ge3xlbHwgSW50ZWdlcihlbCkgcmVzY3VlIGZhbHNlfQojICAgICBhcnIuc29ydF9ieSEgZG8gfGV8CiMgICAgICAgaWYgYWxsX2ludHMKIyAgICAgICAgIGUudG9faSAgIyBTb3J0IHBvc2l0aXZlIGludGVnZXJzCiMgICAgICAgZWxzaWYgZS5pc19hPyhBcnJheSkKIyAgICAgICAgIGUubWFwKCY6dG9fcykuam9pbignXycpCiMgICAgICAgZWxzZQojICAgICAgICAgZS50b19zICAjIFNvcnQgb3RoZXIgZWxlbWVudHMgYXMgc3RyaW5ncwojICAgICAgIGVuZAojICAgICBlbmQKIyAgIGVuZAoKIyAgIGFyci5yZXZlcnNlISBpZiBvcHRzWzpvcmRlcl0gPT0gOmRlc2MgIyBSZXZlcnNlIG9ubHkgZm9yIGV4cGxpY2l0IGRlc2NlbmRpbmcgb3JkZXIKIyAgIGFycgojIGVuZAoKZGVmIGNsZWFudXBfYXJyYXkoYXJyLCBvcHRzID0ge30pCiAgIyBEZXRlcm1pbmUgaWYgYWxsIGVsZW1lbnRzIGFyZSBpbnRlZ2VycyBhbmQgZ2V0IHRoZSBzb3J0IGtleSBmdW5jdGlvbgogIGFyciA9IGFyci5jb21wYWN0LnVuaXEKICBhbGxfaW50cyA9IGFyci5hbGw/IHsgfGVsfCBlbC5pc19hPyhJbnRlZ2VyKSByZXNjdWUgZmFsc2UgfQogIHNvcnRfa2V5ID0gb3B0c1s6c29ydF9rZXldCgogICMgVXNlIGEgc2luZ2xlIHNvcnRfYnkgY2FsbAogIGFyci5zb3J0X2J5ISBkbyB8ZXwKICAgIGlmIHNvcnRfa2V5CiAgICAgIHNvcnRfa2V5LmNhbGwoZSkKICAgIGVsc2lmIGFsbF9pbnRzCiAgICAgIGUudG9faQogICAgZWxzaWYgZS5pc19hPyhBcnJheSkKICAgICAgZS5tYXAoJjp0b19zKS5qb2luKCdfJykKICAgIGVsc2UKICAgICAgZS50b19zCiAgICBlbmQKICBlbmQKCiAgIyBSZXZlcnNlIG9ubHkgZm9yIGV4cGxpY2l0IGRlc2NlbmRpbmcgb3JkZXIKICBhcnIucmV2ZXJzZSEgaWYgb3B0c1s6b3JkZXJdID09IDpkZXNjCgogIGFycgplbmQKCgpjbGFzcyBBcnJheQogIGRlZiBjbGVhbnVwX2FycmF5KG9wdHMgPSB7fSkKICAgIHNvcnRfb3JkZXIgPSBvcHRzWzpvcmRlcl0gfHwgOmFzYwogICAgc29ydF9rZXkgPSBvcHRzWzpzb3J0X2tleV0gfHwgLT4oZSkgeyBlLnRvX3MgfQoKICAgIHNvcnRlZF9hcnJheSA9IGNvbXBhY3Quc29ydF9ieSgmc29ydF9rZXkpCiAgICBzb3J0ZWRfYXJyYXkucmV2ZXJzZSEgaWYgc29ydF9vcmRlciA9PSA6ZGVzYwogICAgc29ydGVkX2FycmF5CiAgZW5kCmVuZAo=