2

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!

2
  • 1
    Looks like JSON. You can use a JSON parser on this string Commented Aug 6, 2019 at 15:08
  • 1
    It smells even more like a X&Y question. Why do you have a string that looks like JSON in the db in the first place? Use native JSON columns instead so that you can search them in the database. Commented Aug 6, 2019 at 16:21

3 Answers 3

1

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"

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

Comments

0

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

Comments

0

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]

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.