Collecting hashes into OpenStruct creates table entry
Use marshal_dump
, although this somewhat defeats the purpose of converting it to an OpenStruct beforehand:
[{:a => :b}].collect {|x| OpenStruct.new(x).marshal_dump }.to_json
=> "[{\"a\":\"b\"}]"
The shorter way would be:
[{:a => :b}].to_json
"[{\"a\":\"b\"}]"
Alternatively you could moneky patch OpenStruct#as_json
as shown in hiroshi's answer:
require "ostruct"
class OpenStruct
def as_json(options = nil)
@table.as_json(options)
end
end
How can I change data collection from hash to array?
Do you just want to change a hash into an array? If so, just use the to_a
method on your hash.
hash = {:a => "something", :b => "something else"}
array = hash.to_a
array.inspect #=> [[:a, "something"], [:b, "something else"]]
Divide data into multiple hashes on the basis of timestamp
Order notifications by timestamp, add a column to select what wil have date only and then use group_by
in Ruby. That should be the easiest way to have it.
For selecting additional column to work you should add attr_accessor
for it.
http://www.ruby-doc.org/core-2.0/Enumerable.html#method-i-group_by
How to convert recursive/nested OpenStruct Object to Hash
Check out docs.
You can use OpenStruct#marshal_dump
:
openstruct_object.marshal_dump
OpenStruct#to_h
will work, too:
openstruct_object.to_h
You can convert your object to hash and then hash to JSON:
openstruct_object.to_h.to_json
But it looks like what you want is a Hash object, not JSON object.
When should I use Struct vs. OpenStruct?
With an OpenStruct
, you can arbitrarily create attributes. A Struct
, on the other hand, must have its attributes defined when you create it. The choice of one over the other should be based primarily on whether you need to be able to add attributes later.
The way to think about them is as the middle ground of the spectrum between Hashes on one side and classes on the other. They imply a more concrete relationship amongst the data than does a Hash
, but they don't have the instance methods as would a class. A bunch of options for a function, for example, make sense in a hash; they're only loosely related. A name, email, and phone number needed by a function could be packaged together in a Struct
or OpenStruct
. If that name, email, and phone number needed methods to provide the name in both "First Last" and "Last, First" formats, then you should create a class to handle it.
Is there a default variable `hash`?
In Ruby, all top level method calls happen on the main
object:
self
#=> main
main
is an object with the class Object
:
self.class
#=> Object
So at the top level, hash
calls the Object#hash
method on the main
object:
hash → fixnum
Generates a Fixnum hash value for this object. This function must have
the property thata.eql?(b)
impliesa.hash == b.hash
.The hash value is used along with eql? by the Hash class to determine
if two objects reference the same hash key. Any hash value that
exceeds the capacity of a Fixnum will be truncated before being used.The hash value for an object may not be identical across invocations
or implementations of Ruby. If you need a stable identifier across
Ruby invocations and implementations you will need to generate one
with a custom method.
For more on the top-level in Ruby, see the blog post What is the Ruby Top-Level?.
Is it possible to create a hash with attributes?
You can use multidimensional Hash?
@books = Book.all
@books_hash = {}
@books.each do |book|
@books_hash[book.id] = {}
@books_hash[book.id][:title] = book.title
@books_hash[book.id][:rating] = book.rating
end
When to use Struct instead of Hash in Ruby?
Structs differ from using hashmaps in the following ways (in addition to how the code looks):
- A struct has a fixed set of attributes, while you add new keys to a hash.
- Calling an attribute that does not exist on an instance of a struct will cause a NoMethodError, while getting the value for a non-existing key from a hash will just return nil.
- Two instances of different structs will never be equal even if the structs have the same attributes and the instances have the same values (i.e.
Struct.new(:x).new(42) == Struct.new(:x).new(42)
is false, whereasFoo = Struct.new(:x); Foo.new(42)==Foo.new(42)
is true). - The
to_a
method for structs returns an array of values, whileto_a
on a hash gets you an array of key-value-pairs (where "pair" means "two-element array") - If
Foo = Struct.new(:x, :y, :z)
you can doFoo.new(1,2,3)
to create an instance ofFoo
without having to spell out the attribute names.
So to answer the question: When you want to model objects with a known set of attributes, use structs. When you want to model arbitrary use hashmaps (e.g. counting how often each word occurs in a string or mapping nicknames to full names etc. are definitely not jobs for a struct, while modeling a person with a name, an age and an address would be a perfect fit for Person = Struct.new(name, age, address)
).
As a sidenote: C structs have little to nothing to do with ruby structs, so don't let yourself get confused by that.
Related Topics
Cross-Platform Means of Getting User's Home Directory in Ruby
How to Create a Form in Rails Without Having to Use Form_For and a Model Instance
Rails Asset Pipeline Not Including Required Files in Application.Js Manifest
Does Multibyte Character Interfere with End-Line Character Within a Regex
How to Rescue Timeout Issues (Ruby, Rails)
Enumerator as an Infinite Generator in Ruby
Install Rvm "Bash /Root/.Rvm/Scripts/Rvm No Such File or Directory"
What Does "No Binary Rubies Available" Mean
Passing Binding or Arguments to Erb from the Command Line
How to Enable Compression in Ruby on Rails
Consuming Non-Rest APIs in Rails with Activeresource
How to Enable Compression in Ruby on Rails