从对象数组中提取ruby哈希元素值

时间:2014-03-07 17:34:35

标签: ruby

我有以下数组

[#<Attachment id: 73, container_id: 1, container_type: "Project", filename: "Eumna.zip", disk_filename: "140307233750_Eumna.zip", filesize: 235303, content_type: nil, digest: "9a10843635b9e9ad4241c96b90f4d331", downloads: 0, author_id: 1, created_on: "2014-03-07 17:37:50", description: "", disk_directory: "2014/03">, #<Attachment id: 74, container_id: 1, container_type: "Project", filename: "MainApp.cs", disk_filename: "140307233750_MainApp.cs", filesize: 1160, content_type: nil, digest: "6b985033e19c5a88bb5ac4e87ba4c4c2", downloads: 0, author_id: 1, created_on: "2014-03-07 17:37:50", description: "", disk_directory: "2014/03">]

我需要从此字符串中提取值73和74,即附件ID。

有没有办法提取这个值

3 个答案:

答案 0 :(得分:2)

以防作者意味着他有一个实际的String实例:

string = '[#<Attachment id: 73, container_id: 1, container_type: "Project", filename: "Eumna.zip", disk_filename: "140307233750_Eumna.zip", filesize: 235303, content_type: nil, digest: "9a10843635b9e9ad4241c96b90f4d331", downloads: 0, author_id: 1, created_on: "2014-03-07 17:37:50", description: "", disk_directory: "2014/03">, #<Attachment id: 74, container_id: 1, container_type: "Project", filename: "MainApp.cs", disk_filename: "140307233750_MainApp.cs", filesize: 1160, content_type: nil, digest: "6b985033e19c5a88bb5ac4e87ba4c4c2", downloads: 0, author_id: 1, created_on: "2014-03-07 17:37:50", description: "", disk_directory: "2014/03">]'

string.scan(/\sid: (\d+)/).flatten =&GT; [“73”,“74”]

答案 1 :(得分:1)

使用Array#collect执行以下操作:

array.collect(&:id)

如果是字符串,请先使用JSON::parse从字符串中取回数组,然后使用Array#collect方法,如下所示:

require 'json'
array = JSON.parse(string)
array.collect(&:id)

答案 2 :(得分:1)

数组的元素(我称之为a)看起来像类Attachment的实例(不是字符串)。您可以通过在IRB中执行e.class来确认,其中e是任何元素a(例如a.first)。如果它返回Attachment,我的假设是正确的。以下假设是这种情况。

@Arup显示了当实例变量@id具有访问器(用于读取)时如何检索它们的值:

a.map(&:id)

(又名collect)。你可以通过执行

来查看@id是否有访问者
e.instance_methods(false)

表示e的任何元素a。这将返回一个数组,其中包含为类Attachment定义的所有实例方法。 (参数false导致Ruby的内置方法被排除。)如果@id没有访问者,则需要使用Object@instance_variable_get

a.map { |e| e.instance_variable_get(:@id) }

(您也可以将参数写为字符串:"@id")。

如果

s = '[#<Attachment id: 73, container_id: 1,..]'

实际上是一个字符串,但你忽略了将它括在(单个)引号中,那么你必须执行

a = eval(s)

在将Attachment的值提取之前将其转换为:@a的实例数组。

听到'点击'?那是我开始我的秒表。我希望看到评论显示需要多长时间,因为建议使用(备受诟病的)eval来骂我。

两个建议:缩短代码到基本要素,避免读者需要水平滚动才能阅读。例如,您可以写下这个:

a = [#<Attachment id: 73, container_id: 1>, #<Attachment id: 74, container_id: 1>]

我删除的所有实例变量都与问题无关。

如果它太长而无法放在一条线上(没有水平滚动,请将其写为:

a = [#<Attachment id: 73, container_id: 1>,
     #<Attachment id: 74, container_id: 1>]

最后,对SO来说是新手,请看一下guide