Itai Schvartzbard
Itai Schvartzbard

Reputation: 23

Ruby on Rails: Get specific substring out of string

a little help with getting data out of a string.

Assuming I executed a sql query and now have a string(which set as hash on db):

"{\"users_associated\":{\"User:4\":6,\"User:22\":28,\"User:30\":36}}"

(Which stands for User:ID : User.display_id)

How can I get a substring the includes all users ids or all their display ids, so I'll have something like 4,22,30 or 6,22,36)?

Thanks!

Upvotes: 2

Views: 586

Answers (3)

changingrainbows
changingrainbows

Reputation: 2701

It's common for data systems to return data in a serialized form, i.e. using data types that facilitate transmission of data. One of these serializable data types is String, which is how your JSON data object has been received.

The first step would be to de-serialize (or parse) this String into a Hash object using JSON.parse and tease out just the data value for key "users_associated".

your_string = "{\"users_associated\":{\"User:4\":6,\"User:22\":28,\"User:30\":36}}"

hash = JSON.parse(your_string)
data = hash["users_associated"]

#=> {"User:4":6, "User:22": 28, "User:30": 36}

Hash#keys gives you an array of a hash's keys.
Hash#values gives you an array of a hash's data values.

keys = data.keys
#=> ["User:4", "User:22", "User:30"]

values = data.values
#=> [6, 28, 36]

Array#join lets you string together the contents of an array with a defined separator, , in this case.

display_ids = keys.join(',')
#=> "6,28,36"

For the User IDs, you could Array#map every element of the values array to replace every string occurrence of "User:" with "", using String#gsub.

user_ids = values.map{|user_id| user_id.gsub("User:", "")}
#=> ["4", "22", "30"]

Then, in a similar way to display_ids, we can Array#join the contents of the user_ids array to a single string.

user_ids = user_ids.join(",")
#=> "4,22,30"

Upvotes: 1

demir
demir

Reputation: 4709

I wrote class for this. If you want, you can add it to your project and use it as follows:

require 'json'

class UserSubstringExtractor
  def initialize(user_json_data)
    @user_json_data = user_json_data
  end

  def display_ids
    user_data.dig('users_associated').values
  end

  def user_ids
    user_data.dig('users_associated').keys.map { |u| u.split(':').last.to_i }
  end

  private

  def user_data
    JSON.parse(@user_json_data)
  end
end

user_json_data = '{"users_associated":{"User:4":6,"User:22":28,"User:30":36}}'
extractor = UserSubstringExtractor.new(user_json_data)

p extractor.display_ids
#=> [6, 28, 36]
p extractor.user_ids
#=> [4, 22, 30]

Upvotes: 0

Flippakitten
Flippakitten

Reputation: 271

You can create two helper methods. I'm leaving return values as arrays because I assume you would need to iterate on them at some point and also converting the user id's to integers.

def extract_display_ids(json)
  json['users_associated'].values
end

def extract_user_ids(some_data)
  json['users_associated'].keys.map{ |key| key.split(':').last.to_i }
end

some_data = JSON.parse("{\"users_associated\":{\"User:4\":6,\"User:22\":28,\"User:30\":36}}")

extract_display_ids(some_data)
#=> [6, 28, 36]
extract_user_ids(some_data)
#=> [4, 22, 30]

If possible though, I would recommend trying to get a better data format:

{ users_associated:
  [{ user_id : 4, display_id:6 }, { user_id : 4, display_id:6 }]
}

Upvotes: 0

Related Questions