Reputation: 3038
I've got the following array
[#<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">]
I need to extract the value 73 and 74 from this string which is Attachment id.
is there any way to extract this value
Upvotes: 1
Views: 1716
Reputation: 110675
The elements of the array (I'll call it a
) look like instances of the class Attachment
(not strings). You can confirm that by executing e.class
in IRB, where e
is any element a
(e.g., a.first
). My assumption is correct if it returns Attachment
. The following assumes that is the case.
@Arup shows how to retrieve the values of the instance variable @id
when it has an accessor (for reading):
a.map(&:id)
(aka collect
). You can see if @id has an accessor by executing
e.instance_methods(false)
for any element e
of a
. This returns an array which contains all the instance methods defined for the class Attachment
. (The argument false
causes Ruby's built-in methods to be excluded.) If @id does not have an accessor, you will need to use Object@instance_variable_get:
a.map { |e| e.instance_variable_get(:@id) }
(You could alternatively write the argument as a string: "@id"
).
If
s = '[#<Attachment id: 73, container_id: 1,..]'
in fact a string, but you neglected to enclose it in (single) quotes, then you must execute
a = eval(s)
to convert it to an array of instances of Attachment
before you can extract the values of :@a
.
Hear that 'click'? That was me starting my stop watch. I want to see how long it will take for a comment to appear that scolds me for suggesting the use of (the much-maligned) eval
.
Two suggestions: shorten code to the essentials and avoid the need for readers to scroll horizontally to read it. Here, for example, you could have written this:
a = [#<Attachment id: 73, container_id: 1>, #<Attachment id: 74, container_id: 1>]
All the instance variables I've removed are irrelevant to the question.
If that had been too long to fit on one lines (without scrolling horizontally, write it as:
a = [#<Attachment id: 73, container_id: 1>,
#<Attachment id: 74, container_id: 1>]
Lastly, being new to SO, have a look at this guide.
Upvotes: 1
Reputation: 118261
Do as below using Array#collect
:
array.collect(&:id)
In case it is a string use JSON::parse
to get the array back from the string first, then use Array#collect
method as below :
require 'json'
array = JSON.parse(string)
array.collect(&:id)
Upvotes: 1
Reputation: 5880
just in case author meant he has an actual String
instance:
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
=> ["73", "74"]
Upvotes: 2