简体   繁体   English

将“s”添加到数组中每个单词的末尾,除了给定数组中的第二个元素,只使用一行代码

[英]Add “s” to the end of each word in an array except for the 2nd element in the given array, only using one line of code

I have an array of single word strings, and I would like to add an 's' to the end of each single word strings except for the 2nd string(element) in the array. 我有一个单字串的数组,我想在每个单字符串的末尾添加一个's',除了数组中的第二个字符串(元素)。 I can easily accomplish this using 9 lines of code, but would prefer to do it with 3 lines of code. 我可以使用9行代码轻松完成此操作,但更喜欢用3行代码完成。

Here's my working code using 9 lines. 这是我使用9行的工作代码。

def add_s(array)
    array.each_with_index.collect do |element, index|
        if index == 1
            element
        else element[element.length] = "s"
            element
        end
    end
end

Here's my broken code while only trying to use 3 lines. 这是我破坏的代码,只是尝试使用3行。

def add_s(array)
    array.each_with_index.map {|element, index| index == 1 ? element : element[element.length] = "s"}
end

Above will return... 以上将返回...

array = ["hand", "feet", "knee", "table"]
add_s(array) => ["s", "feet", "s", "s"]

I'm trying to get... 我想要......

array = ["hand", "feet", "knee", "table"]
add_s(array) => ["hands", "feet", "knees", "tables"]

You should clearly distinguish methods mutating the receiver (the variable they are called on) vs pure methods having no side effects. 你应该清楚地区分变异接收器的方法(它们被调用的变量)与没有副作用的方法。 Also, you should care about what the method returns if you are to use the result of the method. 此外,如果要使用方法的结果,您应该关心方法返回的内容。

Here the method for all indices (but 1 ) returns "s" because it is what the block returns: 这里所有索引(但是1 )的方法返回"s"因为它是块返回的内容:

foo = "bar"
foo[foo.length] = "s"
#⇒ "s"

If you'll check your mutated array afterward, you'll see it was successfully modified to what you wanted. 如果你之后检查你的变异数组,你会发现它已成功修改为你想要的。

input = %w[hand feet knee table]
def add_s(input)
  input.each_with_index.map do |element, index|
    index == 1 ? element : element[element.length] = "s"
  end
  input # ⇐ HERE :: return the mutated object
end
#⇒ ["hands", "feet", "knees", "tables"]

or even easier, do not map , just iterate and mutate: 甚至更容易,不要映射 ,只是迭代和变异:

input = %w[hand feet knee table]
def add_s(input)
  input.each_with_index do |element, index|
    element[element.length] = "s" unless index == 1
  end
end

Instead of mutating the array inplace, the preferred solution would be to return a modified version. 而不是在适当的位置改变数组,首选的解决方案是返回修改后的版本。 For that you should return new values from a block: 为此,您应该从块返回新值:

def add_s(input)
  input.each_with_index.map do |element, index|
    index == 1 ? element : element + "s"
  end
end
#⇒ ["hands", "feet", "knees", "tables"]

If I were given such a task, I would maintain a list of elements to be skipped as well since sooner or later there will be more than one: 如果我被赋予这样的任务,我会保留一个要跳过的元素列表,因为迟早会有不止一个:

input = %w[hand feet knee scissors table]
to_skip = [1, 3]
def add_s(input)
  input.each_with_index.map do |element, index|
    next element if to_skip.include?(index)
    element + "s"
  end
end
#⇒ ["hands", "feet", "knees", "scissors", "tables"]
["hand", "feet", "knee", "table"].map.with_index{|v,i| i==1 ? v : v + 's'}
#=> ["hands", "feet", "knees", "tables"]

map.with_index helps. map.with_index帮助。
Basically map.with_index equals to each_with_index.collect . 基本上map.with_index等于each_with_index.collect
each with collect (same as map ) is superfluous. eachcollect (与map相同)是多余的。

If you want to mutate original array, you can change + to << , but not recommended. 如果要改变原始数组,可以将+更改为<< ,但不建议使用。

I suggest following to achieve as per provided words, 我建议按照提供的话来实现,

arr = ['apple', 'knee', 'crab', 'jails']
arr.each_with_index.map { |x,i| i == 1  ? x : x + 's' }
=> ["apples", "knee", "crabs", "jailss"]

but to avoid unwanted extra 's' at the end of the strings, 但为了避免字符串末尾不需要的额外's',

arr = ['apple', 'knee', 'crab', 'jails']
arr.each_with_index.map { |x,i| i == 1 || x[-1] == 's' ? x : x + 's' }
=> ["apples", "knee", "crabs", "jails"]

Linebreaks in Ruby are completely optional, they can always be replaced by a keyword, a semicolon, or sometimes removed altogether. Ruby中的换行符完全是可选的,它们总是可以用关键字,分号替换,或者有时会被删除。 Therefore, it is always trivially possible to write any Ruby program, no matter how complex, in one line. 因此,无论多么复杂,在一行中编写任何Ruby程序总是很容易的。

Here's your code in one line: 这是你的代码在一行:

def add_s(array) array.each_with_index.collect do |element, index| if index == 1 then element else element[element.length] = "s"; element end end end

However, I am not entirely sure why you want that code on one line, because your original version is much more readable. 但是,我不完全确定为什么要在一行上使用该代码,因为您的原始版本更具可读性。

It's easy to achieve this using 'active_support' 使用'active_support'很容易实现这一点

arr = ["hand", "feet", "knee", "table"]

2.0.0-p648 :023 > require 'active_support/inflector'
 => true

arr.map { |a| arr.index(a) == 1 ? a : a.pluralize }
 => ["hands", "feet", "knees", "tables"]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 找到数组的第二个元素 - Find the 2nd element of array 如何使用每个元素从第二个元素开始在数组中循环? - Ruby - How do I start cycling in an array from the 2nd element using each? - Ruby 迭代数组的每个元素,第一个元素除外 - Iterating over each element of an array, except the first one 二维数组第二元素上的Ruby插值搜索 - Ruby Interpolation Search on 2nd Element of a Two Dimensional Array 将每个单词大写,除了数组中的选定单词 - Capitalize each word except selected words in an array 有没有办法使用一行代码以独特的方式获取一个数组并修改每个单独的元素? - Is there a way to take an array and modify each individual element in a unique way using a single line of code? 从哈希数组中的每个组中获取第二项的聪明方法? - Clever Way To Get 2nd Item From Each Group In Array Of Hashes? 使输入的每个单词成为数组元素 - Making each word of input an array element 如何一次将一个单词中的一个字母大写,然后将带有大写字母的单词的每个实例添加到数组中? - How can I capitalize a letter from a word one at a time, then add each instance of the word with a caps letter into a array? 如何从Ruby中的数组中获取第1,第2和第5个元素? - How to get the the 1st, 2nd and 5th element from an array in Ruby?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM