未定义的方法`split'for []:Array Ruby codewars“谁喜欢它?”卡塔

时间:2016-11-25 18:35:06

标签: arrays ruby string function

我在输入数组时遇到问题,在CodeWars上尝试Ruby挑战。

以下是指示: 实现一个函数like :: [String] - > String,必须包含输入数组,包含喜欢项目的人的姓名。它必须返回显示文本,如示例所示:

CDM = (~CD .* CDM) + (CD .* reshape(replace_color, [1 1 3]));

我的试用代码是:

likes [] // must be "no one likes this"
likes ["Peter"] // must be "Peter likes this"
likes ["Jacob", "Alex"] // must be "Jacob and Alex like this"
likes ["Max", "John", "Mark"] // must be "Max, John and Mark like this"
likes ["Alex", "Jacob", "Mark", "Max"] // must be "Alex, Jacob and 2 others like this"

这就是编译返回的内容:

def likes(names)
  arr = Array.[](names.split(/\W+/))
  if arr.size == 0
    var = "no one likes this"
    return var
  elsif  arr.size == 1
    return  arr[0]+ " likes this "
  elsif  arr.size == 2
    return  arr[0] + "and #{arr[1]} likes this "
  elsif  arr.size == 3
    return "  #{arr[0]}, #{arr[1]} and #{arr[2]} likes this "
  elsif  arr.size >3
    return  "#{arr[0]}, #{arr[1]} and #{arr.size-1} likes this "
  end
end

click to see image with error

3 个答案:

答案 0 :(得分:1)

此代码中存在许多混淆,需要在它开始工作之前解决。如果你想拉出一个数组的大块,你可以使用slice,或者简单的数组符号names[0,2]来提取前两个。

当您对自己接受的论点充满好奇时,通常只需添加一些代码即可找到:

p names.class.inspect

那会抛出一些东西,告诉你收到了什么样的对象。在这种情况下,它是一个数组。

对于初学者来说,在代码方面进行思考是一个常见的错误,就像你在这里测试特定数组长度的非常狭窄的情况一样。真的只有三个条件:超过三个人,没有人,以及默认情况。

首先关注改变并正确的措辞:

def name_list(names)
  if (names.empty?)
    # An empty list means:
    'nobody'
  else
    # Special case for the last element in the list, so pull it off
    *names, last = names

    # If there's more than two names remaining then change the
    # phrasing of the last element to indicate "N others"
    if (names.length > 2)
      last = '%d others' % (names.length - 1)
    end

    # Join these together in the "X, Y, and Z" format.
    (names[0,2] + [ 'and ' + last ]).join(', ')
  end
end

您可以通过多种方式实现这一目标,但这是一种相当简洁的方法,只需最少的分支机构。您希望避免重复自己,以及如何制作错误,并将常见行为合并到公共代码中。 "喜欢这个"部分是一个这样的例子。

现在你可以这样做:

def likes(names)
  name_list(names) + ' liked this'
end

这样一来,如果你想改变措辞就有一个地方去做,你可以在你处理名单或事物清单的其他情况下重复使用这种方法。

答案 1 :(得分:1)

我会这样写。

def say_names(name_arr)
  case name_arr.size
  when 0 then "no one likes this"
  when 1 then "%s likes this"           % name_arr
  when 2 then "%s and %s like this"     % name_arr
  when 3 then "%s, %s and %s like this" % name_arr
  else "%s, %s and %d others like this" % (name_arr[0,2] + [name_arr.size-2])
  end
end

say_names []
  #=> "no one likes this" 
say_names ["Peter"]
  #=> "Peter likes this" 
say_names ["Jacob", "Alex"]
  #=> "Jacob and Alex like this" 
say_names ["Max", "John", "Mark"]
  #=> "Max, John and Mark like this" 
say_names ["Alex", "Jacob", "Mark", "Max", "Trixie"]
  #=> "Alex, Jacob and 3 others like this" 

编写方法的方法可能略短,但我喜欢这种方式。

答案 2 :(得分:0)

使用原始代码并添加简单的三元表达式

def likes(names)
  arr = names.empty? ? [] : Array.[](names.split(/\W+/))
  if arr.size == 0
    var = "no one likes this"
    return var
  elsif  arr.size == 1
    return  arr[0]+ " likes this "
  elsif  arr.size == 2
    return  arr[0] + "and #{arr[1]} likes this "
  elsif  arr.size == 3
    return "  #{arr[0]}, #{arr[1]} and #{arr[2]} likes this "
  elsif  arr.size >3
    return  "#{arr[0]}, #{arr[1]} and #{arr.size-1} likes this "
  end
end

应该做的伎俩。

更简洁的方法是删除所有返回语句,因为ruby隐式返回最后评估的内容。就这样:

def likes(names)
      arr = names.empty? ? [] : Array.[](names.split(/\W+/))
      if arr.size == 0
        "no one likes this"
      elsif  arr.size == 1
        arr[0]+ " likes this "
      elsif  arr.size == 2
        arr[0] + "and #{arr[1]} likes this "
      elsif  arr.size == 3
        "#{arr[0]}, #{arr[1]} and #{arr[2]} likes this "
      elsif  arr.size >3
        "#{arr[0]}, #{arr[1]} and #{arr.size-1} likes this "
      end
    end

最后,你可以把它分成两行,但是你会牺牲可读性:

def likes(names)
  arr = names.empty? ? [] : Array.[](names.split(/\W+/))
  arr.size == 0 ? "no one likes this" : arr.size == 1 ? arr[0]+ " likes this " : arr.size == 2 ? arr[0] + "and #{arr[1]} likes this" : arr.size == 3 ? "#{arr[0]}, #{arr[1]} and #{arr[2]} likes this " : "#{arr[0]}, #{arr[1]} and #{arr.size-1} likes this "
end