获取数组长度而不使用长度

时间:2017-11-07 02:16:34

标签: arrays ruby

在一个关于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首先检查长度,然后检查每个元素上的==。我正在尝试实现长度,以便再次卡住。

2 个答案:

答案 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