在一个关于exercism.io的完全设计的问题中,我的任务是想出一种方法来获取数组的长度/大小而不使用任何可枚举的方法。
我原本只是:
arr = [1,3,4]
ctr = 0
while arr[ctr]
ctr += 1
end
ctr
问题是我可以arr = Array.new(5)
,[nil, nil, nil, nil, nil]
。
我找到了两种方法:
ctr = 0
loop do
element = arr.fetch(ctr) { 'outofbounds!' }
break if element == 'outofbounds!'
ctr += 1
end
ctr
我想在不使用Array#fetch
的情况下这样做,因为索引越界很可能会看到已知的长度(这也是我想要实现的)。
另一种解决方案:
ctr = 0
copy = arr.dup
while copy != []
ctr += 1
copy.pop
end
ctr
这感觉稍微正确,但==
Array
首先检查长度,然后检查每个元素上的==
。我正在尝试实现长度,以便再次卡住。
答案 0 :(得分:2)
这是一个故意真正在那里的解决方案,因为这个问题是不使用核心API做的事情:
def array_length(a)
b = a.dup
c = [ ]
f = 0
while (b != [ ])
c.push('')
b.pop
f = 1
end
e = c.join("\x01").to_s.unpack('C*')
while (e[0])
f += e.pop
end
f
end
答案 1 :(得分:1)
我认为你的第一个解决方案很接近。当然,问题是nil
是列表的有效元素。因此,最简单的解决方案是在末尾添加一个sentinel值, never 将成为列表的元素。
我不时使用这个成语;您只需创建Object
类的全新实例并将其用作值。没有任何其他对象可以比较等于它,并且它不可能是列表的元素,因为它刚刚组成。
arr = [1,3,4]
end_of_list = Object.new
copy = arr.dup
copy.push end_of_list
ctr = 0
while end_of_list != copy[ctr]
ctr += 1
end
ctr