Created
June 7, 2017 05:04
-
-
Save dimanyc/961fd7f89773933e57e33d5d402b0c4f to your computer and use it in GitHub Desktop.
MemberUniqualizer Array Refinement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MemberUniquelizer | |
refine Array do | |
# makes each member within an array | |
# unique by appending a unique number | |
def uniquelize(ary = self) | |
ary.map { |member| format_member(member) } | |
.flatten | |
.uniq | |
end | |
private | |
# returns pure or formated member string | |
# depending on present repetitions | |
def format_member(member) | |
contains_repetitions?(member) ? append_sequence(member) : member | |
end | |
# checks for repeated members | |
def contains_repetitions?(member) | |
repetitions_hash[member].count > 1 | |
end | |
# returns an array of members | |
# with appended sequential numbes | |
def append_sequence(member) | |
repetitions_hash[member].map.with_index do |repeated_member, index| | |
name = repeated_member.nil? ? 'empty' : repeated_member | |
"#{name}_repeat#{index + 1}" | |
end | |
end | |
# returns a hash containg elements and | |
# their number of occurances within array | |
def repetitions_hash | |
group_by { |member| member } | |
end | |
end | |
end | |
#------------------------------------------------------------------------# | |
### MemberUniquelizer spec | |
require 'rails_helper' | |
using MemberUniquelizer | |
RSpec.describe MemberUniquelizer do | |
it 'should add a counter to repeated memebers of an Array' do | |
ary = ['a', 'a', 'c'] | |
expect(ary.uniquelize) | |
.to eq(['a_repeat1', 'a_repeat2', 'c']) | |
end | |
it 'should count the number of repetitions' do | |
ary = ['a', 'a', 'c'] | |
expect(ary.send(:repetitions_hash)) | |
.to eq({ | |
'a' => ['a', 'a'], | |
'c' => ['c'] | |
}) | |
end | |
it 'should append sequential number to repeated members' do | |
ary = ['a', 'a', 'c'] | |
expect(ary.send(:append_sequence, 'a')) | |
.to include('a_repeat1', 'a_repeat2') | |
end | |
it 'should identify whether a memeber is repeated' do | |
ary = ['a', 'a', 'c'] | |
expect(ary.send(:contains_repetitions?, 'a')) | |
.to be_truthy | |
end | |
it 'should identify whether a memeber is unique' do | |
ary = ['a', 'a', 'c'] | |
expect(ary.send(:contains_repetitions?, 'c')) | |
.to be_falsey | |
end | |
it 'should format repeated members' do | |
ary = ['a', 'a', 'c'] | |
expect(ary.send(:format_member, 'a')) | |
.to include('a_repeat1', 'a_repeat2') | |
end | |
it 'should not format unique members' do | |
ary = ['a', 'a', 'c'] | |
expect(ary.send(:format_member, 'c')) | |
.to include('c') | |
end | |
context 'when supplied array contains empty members' do | |
context 'when supplied array contains a single empty member' do | |
let(:ary) { ['a', nil, 'a', 'c'] } | |
it 'should keep the empty member and proceed with the rest' do | |
expect(ary.uniquelize) | |
.to include('a_repeat1', nil, 'a_repeat2', 'c') | |
end | |
end # when single nil | |
context 'when supplied array contains multiple empty members' do | |
let(:ary) { [ nil, nil, 'a', 'a'] } | |
it 'should keep the empty member and proceed with the rest' do | |
expect(ary.uniquelize) | |
.to include( | |
'empty_repeat1', | |
'empty_repeat2', | |
'a_repeat1', | |
'a_repeat2') | |
end | |
end # when multiple nils | |
end # when include nil | |
context 'when supplied array contains non-string members' do | |
let(:ary) { [1, 1, :foo, :foo] } | |
it 'should turn these members intro strings' do | |
expect(ary.uniquelize) | |
.to include( | |
'1_repeat1', | |
'1_repeat2', | |
'foo_repeat1', | |
'foo_repeat2') | |
end | |
end # with non-strings | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment