合并数组中的每n个项目

时间:2018-12-22 13:24:56

标签: arrays ruby

我正在尝试解决CodeWars上的以下Ruby难题:

  

编写一个名为merge_every的函数,该函数接受3个参数:2个数组   和一个数字,指示要插入第二个项目的数量   将项目排列到第一个。第三个参数是可选的,应该   默认为4

     

请考虑一下,因为您有一系列正常事件和   特色事件,并且您想将两者合并以产生一个数组   具有特色的事件每3个项目就会显示一次。

event_ids = [1, 2, 3, 4, 5, 6, 7]
featured_event_ids = [10, 11]
merge_every(event_ids, featured_event_ids, 3)
# => [1, 2, 3, 10, 4, 5, 6, 11, 7]
     

如果第一个数组应在第二个数组之前完成,则其余   第二个被丢弃。而如果第二个在第一个之前用完,   应该保留第一个数组的整体。应该计数为0   或更少,则不应插入任何项目,并且如果目标数组为空,   比应返回一个空数组。

     

更多示例

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
letters = ['a', 'b', 'c', 'd']
merge_every(numbers, letters)
# => [1, 2, 3, 4, 'a', 5, 6, 7, 8, 'b', 9, 10]

merge_every(letters, numbers)
# => ['a', 'b', 'c', 'd']

merge_every(letters, numbers, 2)
# => ['a', 'b', 1, 'c', 'd']

我的解决方法是:

def merge_every(target, source, count=4)

  count == 0 ? number_of_source_in_target = 0 : number_of_source_in_target = target.count / count
  insertion_number = count
  source_number = 0

    if insertion_number == 0 || source.count == 0 || number_of_source_in_target <= 1
        target
    elsif target.count % insertion_number == 0
      number_of_source_in_target -= 1
      while source_number < number_of_source_in_target && source_number < source.count do
        modulo_0_return = target.insert(insertion_number, source[source_number])
        insertion_number += (count + 1)
        source_number += 1
      end
      modulo_0_return
    else
      while source_number < number_of_source_in_target && source_number < source.count do
          modulo_numbers_return = target.insert(insertion_number, source[source_number])
          insertion_number += (count + 1)
          source_number += 1
      end
      modulo_numbers_return
    end
end

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
letters = ['a', 'b', 'c', 'd']
print merge_every(numbers, letters, 3)

当我在计算机上运行代码时,我得到了正确的答案,但是在CodeWars网站上,他们的检查器给出了不同的输出。区别在于:

merge_every(numbers, letters, 3)
# My Terminal: [1, 2, 3, 'a', 4, 5, 6, 'b', 7, 8, 9, 'c', 10]
# CodeWars "checker": [1, 2, 3, "a", 4, "a", 5, "b", 6, 7, 8, "c", "b", 9, 10]

merge_every(numbers, letters, 1)
# My Terminal: [1, 'a', 2, 'b', 3, 'c', 4, 'd', 5, 6, 7, 8, 9, 10]
# CodeWars "checker": [1, "a", 2, "b", 3, "c", "a", "d", 4, "a", 5, "b", 6, 7, 8, "c", "b", 9, 10]

我不知道为什么。谁能帮我找出这种差异?

3 个答案:

答案 0 :(得分:0)

我不确定代码大战在做什么,但可能是它多次运行您的方法。您的代码要做的一件事是使数组target发生突变,因此,如果您这样做了。

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
letters = ['a', 'b', 'c', 'd']
merge_every(numbers, letters, 3)
=> [1, 2, 3, 'a', 4, 5, 6, 'b', 7, 8, 9, 'c', 10]

但是,如果您选中numbers,就会发现它们已更改...

p numbers
=> [1, 2, 3, 'a', 4, 5, 6, 'b', 7, 8, 9, 'c', 10]

因此,您的数字数组将发生更改,并且每次使用相同的输入对象运行merge_every时,您都会得到不同的结果(并再次更改numbers数组)

您可以尝试确保在数组的副本(副本)上而不是数组本身上运行代码...看上去相同但对象不同的数组。这样,当代码更改target时,原始输入arry不变。

def merge_every(target, source, count=4)
  target = target.dup
  ...

答案 1 :(得分:0)

这是使用内置功能Enumerable#each_slice的选项,也许您也可以在codewar中进行测试以查看是否存在某些问题:

n = 3
event_ids.each_slice(n).zip(featured_event_ids).flatten.compact
#=> [1, 2, 3, "a", 4, 5, 6, "b", 7]

检查其工作方式可能会提供提示。 需要添加一个条件来避免此结果,例如使用n=6

#=> [1, 2, 3, 4, 5, 6, "a", 7, "b"]

答案 2 :(得分:0)

如果您的代码通过了测试,但未通过CodeWar的测试,则最可能的解释是您的测试不正确,或者更有可能是不完整的。

这是一种类似于Ruby的插入方式。

def insert_em(arr, insertions, after_every = 4)
  return arr if after_every <= 0
  enum_arr = arr.to_enum
  isize = insertions.size
  arr.size.times.with_object([]) do |i,a|
    a << enum_arr.next
    a << insertions[i/after_every] if
      i <= after_every*isize && ((i+1) % after_every).zero?
  end
end

arr = (1..10).to_a

insert_em(arr, [:a, :b, :c],  -1)
  #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
insert_em(arr, [:a, :b, :c],  0)
  #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
insert_em(arr, [:a, :b, :c],  1)
  #=> [1, :a, 2, :b, 3, :c, 4, 5, 6, 7, 8, 9, 10]
insert_em(arr, [:a, :b, :c],  2)
  #=> [1, 2, :a, 3, 4, :b, 5, 6, :c, 7, 8, 9, 10]
insert_em(arr, [:a, :b, :c],  4)
  #=> [1, 2, 3, 4, :a, 5, 6, 7, 8, :b, 9, 10]
insert_em(arr, [:a, :b, :c],  5)
  #=> [1, 2, 3, 4, 5, :a, 6, 7, 8, 9, 10, :b]
insert_em(arr, [:a, :b, :c], 11)
  #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
insert_em(arr, [])
  #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
insert_em([], [:a, :b, :c])
  #=> []
insert_em([], [])
  #=> []