【问题标题】:How do I convert this Ruby String into an Array?如何将此 Ruby 字符串转换为数组?
【发布时间】:2012-05-18 13:35:25
【问题描述】:

将以下 Ruby 字符串转换为数组的最佳方法是什么(我使用的是 ruby​​ 1.9.2/Rails 3.0.11)

Rails 控制台:

>Item.first.ingredients
=> "[\"Bread, whole wheat, 100%, slice\", \"Egg Substitute\", \"new, Eggs, scrambled\"]"
>Item.first.ingredients.class.name
=> "String"
>Item.first.ingredients.length
77

想要的输出:

>Item.first.ingredients_a
["Bread, whole wheat, 100%, slice", "Egg Substitute", "new, Eggs, scrambled"]
>Item.first.ingredients_a.class.name
=> "Array
>Item.first.ingredients_a.length
=> 3

如果我这样做,例如:

>Array(Choice.first.ingredients)

我明白了:

=> ["[\"Bread, whole wheat, 100%, slice\", \"Egg Substitute\", \"new, Eggs, scrambled\", \"Oats, rolled, old fashioned\", \"Syrup, pancake\", \"Water, tap\", \"Oil, olive blend\", \"Spice, cinnamon, ground\", \"Seeds, sunflower, kernels, dried\", \"Flavor, vanilla extract\", \"Honey, strained/extracted\", \"Raisins, seedless\", \"Cranberries, dried, swtnd\", \"Spice, ginger, ground\", \"Flour, whole wheat\"]"] 

我确信一定有一些明显的方法可以解决这个问题。

为清楚起见,这将在表单中的 textarea 字段中进行编辑,因此应尽可能安全。

【问题讨论】:

  • 最好的办法是修改ingredients方法。
  • 如果你不能改变配料方法,你至少应该把它贴出来,这样我们就可以看到它的输出了。覆盖它当然是一种选择,但我们必须看到它才能提供帮助。

标签: ruby-on-rails ruby arrays string


【解决方案1】:
class Item
  def ingredients_a
    ingredients.gsub(/(\[\"|\"\])/, '').split('", "')
  end
end
  1. 去掉多余的字符
  2. 使用分隔模式拆分为数组元素

【讨论】:

  • 我真的很喜欢 JSON.parse 的答案,但是这个应该可以工作,并且可能是解决这个问题的最直接的方法。
  • +1 这是对这个问题最直接的答案。 优雅的答案首先需要更多关于数组如何变成字符串的信息。
【解决方案2】:

如果您的字符串数组是标准 JSON 格式,只需使用 JSON.parse()

【讨论】:

    【解决方案3】:

    你所拥有的看起来像 JSON,所以你可以这样做:

    JSON.parse "[\"Bread, whole wheat, 100%, slice\", \"Egg Substitute\", \"new, Eggs, scrambled\"]"
    #=> ["Bread, whole wheat, 100%, slice", "Egg Substitute", "new, Eggs, scrambled"]
    

    这避免了很多使用eval 的恐惧。

    虽然您首先应该考虑一下为什么要这样存储数据,并考虑更改它,这样您就不必这样做了。此外,您可能应该将其解析为ingredients 中的数组,以便该方法返回更有意义的内容。如果您几乎总是对方法的返回值执行相同的操作,则该方法是错误的。

    【讨论】:

    • 如果它实际上是 JSON,我只会这样做。看看ingredients 方法就知道了。
    • @MarkThomas 完全同意,但没有提供很多关于为什么数据是字符串格式的信息,所以(不幸的是)必须做出假设。
    【解决方案4】:

    就像 Mark Thomas 所说,修改你的成分方法,除非你真的想要两个单独的方法,分别返回一个字符串和一个数组。我假设您真的只想返回一个数组。为了论证,假设您的成分方法当前返回一个名为ingredients_string 的变量。像这样修改你的方法:

    def ingredients
      ...
      ingredients_array = ingredients_string.split('"')
      ingredients_array.delete_if { |element| %(", "[", "]").include? element }
      ingredients_array
    end
    

    【讨论】:

    • 作为记录,我认为 Andrew Marshall 的 JSON.parse 建议要优雅得多。
    【解决方案5】:

    不确定这是否起作用,但是如果您想使用数组作为属性会发生什么,您可能需要考虑序列化..

    class Item << ActiveWhatever
      serialize :ingredients, Array
    
      ...
    end
    

    更多关于序列化的信息在这里http://api.rubyonrails.org/classes/ActiveRecord/Base.html

    【讨论】:

    • 是的,所以我想我可以将数据存储到一个可序列化的数组字段中,但我仍然从一个看起来像上面格式的字符串开始:).. 所以需要转换它到一个数组把它放在那里:)。
    【解决方案6】:

    看起来ingredients 方法返回了结果返回数组的.inspect 输出。这样输出不是很有用。你有能力改变它以返回一个普通的数组吗?

    我会做的是使用eval,这只会增加已经hacky代码的hackiness。

    【讨论】:

    • 我同意你的观点,如果可能的话,我希望避免使用“eval”。如有必要,我可能会覆盖该方法或进行其他调用,但我仍然想知道将字符串转换为数组的最佳方法是什么,因为数据类型可能不会改变。我可能会将数据存储在可序列化的文本字段中,并以我猜想的某种格式存储数组。
    • @NathanW 我认为问题是,为什么你的数组首先是字符串形式的?
    • +1 虽然这看起来更像是一条评论,但在给定信息有限的情况下,它非常接近可能是正确答案。
    • @andrew,我允许通过表单中的文本区域编辑数组。这个例子是信息是如何通过参数到达的。如果有其他更好的方法来维护数组,那就太好了。
    • @NathanW 然后我假设它 is JSON 被发送?如果不是,它应该是。
    猜你喜欢
    • 1970-01-01
    • 2021-11-26
    • 2014-10-16
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多