1

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

3
  • How are you getting this ? Commented Mar 7, 2014 at 17:43
  • it's a value returned by a redmine method. (attach_files) Commented Mar 7, 2014 at 18:01
  • To clarify the question, and stem further downvotes, I suggest you: 1. replace 'string' in the first sentence with 'array'; 2. delete 'from the string which is Attachment id'; and 3. in IRB, define the array as a and report the class retuned by a.class, which I expect will be Attachment. Commented Mar 7, 2014 at 21:04

3 Answers 3

2

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"]

Sign up to request clarification or add additional context in comments.

Comments

1

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)

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.