i'm creating method transpose square 2-d arrays. method passes every test, except "does not modify original array" one. i'm working on duped array, i'm confused on why test failing.
code:
class array def my_transpose orig_arr = self.dup; array = [] orig_arr[0].length.times temp_arr = [] orig_arr.each { |arr| temp_arr << arr.shift } array << temp_arr end array end end rspec:
describe array describe "#my_transpose" let(:arr) { [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] } let(:small_arr) { [ [1, 2], [3, 4] ] } "transposes small matrix" expect(small_arr.my_transpose).to eq([ [1, 3], [2, 4] ]) end "transposes larger matrix" expect(arr.my_transpose).to eq([ [1, 4, 7], [2, 5, 8], [3, 6, 9] ]) end "should not modify original array" small_arr.my_transpose expect(small_arr).to eq([ [1, 2], [3, 4] ]) end "should not call built-in #transpose method" expect(arr).not_to receive(:transpose) arr.my_transpose end end end output:
7) array#my_transpose should not modify original array failure/error: expect(small_arr).to eq([ expected: [[1, 2], [3, 4]] got: [[], []] (compared using ==) # ./spec/00_array_extensions_spec.rb:123:in `block (3 levels) in <top (required)>'
when call dup on array, duplicates array itself; array's contents not duplicated. so, example:
a = [[1,2],[3,4]] b = a.dup a.object_id == b.object_id # => false a[0].object_id == b[0].object_id # => true thus, modifications a itself not reflected in b (and vice versa), modifications in elements of a reflected in b, because elements same objects.
that being case, problem crops here:
orig_arr.each { |arr| temp_arr << arr.shift } arr element of orig_arr, also element of self. if did remove it orig_arr, not remove self, if change it, it's changed, no matter how accessing it, , turns out, array#shift destructive operation.
probably smallest change make code make work expect use each_with_index, , use index arr, rather calling arr.shift, so:
orig_arr.each_with_index { |arr,i| temp_arr << arr[i] } in fact, though, once you're doing that, you're not doing destructive operations @ , don't need orig_arr, can use self.
Comments
Post a Comment