Collecting Hashes into Openstruct Creates "Table" Entry

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 that a.eql?(b) implies a.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, whereas Foo = Struct.new(:x); Foo.new(42)==Foo.new(42) is true).
  • The to_a method for structs returns an array of values, while to_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 do Foo.new(1,2,3) to create an instance of Foo 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



Leave a reply



Submit