我在输入数组时遇到问题,在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
答案 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