How can I create a dynamic array, whose default element will empty hash?

Hi,

If I write `array = Array.new(4) { {} }` , it will create an array of empty hashes of size 4. Now if I do array[3], array[2] etc, I would get `{}`. But now, if I do `array[4]` or `array[5]`, I will get `nil`. Reason is clear. But I am looking for a way to get an empty hash ( for first time ), for any index access from `array` ?

I mean

array[7] # => {}
array[11] # => {} # although I created array of size 4.

Regards,
Arup Rakshit

Only way I can think of is if you subclass Array, and override #? You'd then
have to answer all the questions of how that interface would work in your case.
For example:

ruby -e 'a = ; a[4] = true; puts a.inspect' # => [nil, nil, nil, nil, true]

Your array is now length 5.

And what about slices?

I wouldn't suggest this route however, but it does answer the question. I think
I would add another method onto that new class, so it's more clear:

def item_or_hash_by_index(index)
  self[index].nil? ? self[index] = {} : self[index]
end

···

On Thu, May 15, 2014 at 08:17:51PM +0800, Arup Rakshit wrote:

Hi,

If I write `array = Array.new(4) { {} }` , it will create an array of empty hashes of size 4. Now if I do array[3], array[2] etc, I would get `{}`. But now, if I do `array[4]` or `array[5]`, I will get `nil`. Reason is clear. But I am looking for a way to get an empty hash ( for first time ), for any index access from `array` ?

I mean

array[7] # => {}
array[11] # => {} # although I created array of size 4.

Regards,
Arup Rakshit

I was actually looking for Hash#default= (Class: Hash (Ruby 2.1.1)). Why Array class don't have any such method, like Hash class has ? `Hash#default=` is very useful although.

Regards,
Arup Rakshit

Only way I can think of is if you subclass Array, and override #? You'd then
have to answer all the questions of how that interface would work in your case.
For example:

ruby -e 'a = ; a[4] = true; puts a.inspect' # => [nil, nil, nil, nil, true]

Your array is now length 5.

And what about slices?

I wouldn't suggest this route however, but it does answer the question. I think
I would add another method onto that new class, so it's more clear:

def item_or_hash_by_index(index)
self[index].nil? ? self[index] = {} : self[index]
end

···

On Thursday, 15 May 2014 6:18 PM, Craig Monson <craig@malachiarts.com> wrote:

On Thu, May 15, 2014 at 08:17:51PM +0800, Arup Rakshit wrote:

Hi,

If I write `array = Array.new(4) { {} }` , it will create an array of empty hashes of size 4. Now if I do array[3], array[2] etc, I would get `{}`. But now, if I do `array[4]` or `array[5]`, I will get `nil`. Reason is clear. But I am looking for a way to get an empty hash ( for first time ), for any index access from `array` ?

I mean

array[7] # => {}
array[11] # => {} # although I created array of size 4.

Regards,
Arup Rakshit

Hi Arup,

Look,

a = Array.new

a
# => # Empty

a[5] = "five"

a
# => [nil, nil, nil, nil, nil, "five"]

Look, a[0] is "really" nil by now!

If we use Hash

h = Hash.new
h[5] = "five"
h
# => {5=>"five"}

There's no nil on key 0 or 1 or 2...

h[1]
# => nil

h.fetch(1)

# It raises an exception!!!

KeyError: key not found: 1
from (irb):11:in `fetch'
from (irb):11
from /Users/abinoam/.rvm/rubies/ruby-2.1.0/bin/irb:11:in `<main>'

h.fetch(1) { "My Defaul Value" }

# => "My Default Value"

If you really need to use Array you can simply use an "or" like

my_var = a[1] || "My Default Value"

Abinoam Jr.

···

On Thu, May 15, 2014 at 9:57 AM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

I was actually looking for Hash#default=
(Class: Hash (Ruby 2.1.1)). Why
Array class don't have any such method, like Hash class has ?
`Hash#default=` is very useful although.

Regards,
Arup Rakshit
On Thursday, 15 May 2014 6:18 PM, Craig Monson <craig@malachiarts.com> > wrote:
Only way I can think of is if you subclass Array, and override #? You'd
then
have to answer all the questions of how that interface would work in your
case.
For example:

ruby -e 'a = ; a[4] = true; puts a.inspect' # => [nil, nil, nil, nil,
true]

Your array is now length 5.

And what about slices?

I wouldn't suggest this route however, but it does answer the question. I
think
I would add another method onto that new class, so it's more clear:

def item_or_hash_by_index(index)
  self[index].nil? ? self[index] = {} : self[index]
end

On Thu, May 15, 2014 at 08:17:51PM +0800, Arup Rakshit wrote:

Hi,

If I write `array = Array.new(4) { {} }` , it will create an array of
empty hashes of size 4. Now if I do array[3], array[2] etc, I would get
`{}`. But now, if I do `array[4]` or `array[5]`, I will get `nil`. Reason is
clear. But I am looking for a way to get an empty hash ( for first time ),
for any index access from `array` ?

I mean

array[7] # => {}
array[11] # => {} # although I created array of size 4.

Regards,
Arup Rakshit

Thanks Abinoam for your reply. I actually looking to create an Array, whose
default elements will be *different hash( means object_id should be different
)*. So that on runtime I can access any array element, and add key to the
hash, with a value.

Look the answer - ruby - Best way to check for nil and update hash value - Stack Overflow . The similar thing I am looking for an
array if can be implemented. If `Array#default=` exist, then all problem can
be solved, but it exist for Hash, not Array.

···

On Thursday, May 15, 2014 01:42:28 PM you wrote:

Hi Arup,

Look,

a = Array.new

a
# => # Empty

a[5] = "five"

a
# => [nil, nil, nil, nil, nil, "five"]

Look, a[0] is "really" nil by now!

If we use Hash

h = Hash.new
h[5] = "five"
h
# => {5=>"five"}

There's no nil on key 0 or 1 or 2...

h[1]
# => nil

h.fetch(1)

# It raises an exception!!!

KeyError: key not found: 1
from (irb):11:in `fetch'
from (irb):11
from /Users/abinoam/.rvm/rubies/ruby-2.1.0/bin/irb:11:in `<main>'

> h.fetch(1) { "My Defaul Value" }

# => "My Default Value"

If you really need to use Array you can simply use an "or" like

my_var = a[1] || "My Default Value"

--

Regards,
Arup Rakshit

why not use a hash then?

···

On Thu, May 15, 2014 at 10:36:14PM +0630, Arup Rakshit wrote:

On Thursday, May 15, 2014 01:42:28 PM you wrote:
> Hi Arup,
>
> Look,
>
> a = Array.new
>
> a
> # => # Empty
>
> a[5] = "five"
>
> a
> # => [nil, nil, nil, nil, nil, "five"]
>
> Look, a[0] is "really" nil by now!
>
> If we use Hash
>
> h = Hash.new
> h[5] = "five"
> h
> # => {5=>"five"}
>
> There's no nil on key 0 or 1 or 2...
>
> h[1]
> # => nil
>
> h.fetch(1)
>
> # It raises an exception!!!
>
> KeyError: key not found: 1
> from (irb):11:in `fetch'
> from (irb):11
> from /Users/abinoam/.rvm/rubies/ruby-2.1.0/bin/irb:11:in `<main>'
>
> > h.fetch(1) { "My Defaul Value" }
>
> # => "My Default Value"
>
> If you really need to use Array you can simply use an "or" like
>
> my_var = a[1] || "My Default Value"
>

Thanks Abinoam for your reply. I actually looking to create an Array, whose
default elements will be *different hash( means object_id should be different
)*. So that on runtime I can access any array element, and add key to the
hash, with a value.

Look the answer - ruby - Best way to check for nil and update hash value - Stack Overflow . The similar thing I am looking for an
array if can be implemented. If `Array#default=` exist, then all problem can
be solved, but it exist for Hash, not Array.

--

Regards,
Arup Rakshit

Hi Arup,

Repeating myself and agreeing with Craig, you're in need of a Hash not an Array.

But, the same "or" workaround from my previous email will fit.

my_var = a[ix] || Hash.new

Everytime a[ix] is nil it will return a fresh new Hash (with different
object id).

Hope it helps you.

Best regards,
Abinoam Jr.

···

On Thu, May 15, 2014 at 2:15 PM, Craig Monson <craig@malachiarts.com> wrote:

why not use a hash then?

On Thu, May 15, 2014 at 10:36:14PM +0630, Arup Rakshit wrote:

On Thursday, May 15, 2014 01:42:28 PM you wrote:
> Hi Arup,
>
> Look,
>
> a = Array.new
>
> a
> # => # Empty
>
> a[5] = "five"
>
> a
> # => [nil, nil, nil, nil, nil, "five"]
>
> Look, a[0] is "really" nil by now!
>
> If we use Hash
>
> h = Hash.new
> h[5] = "five"
> h
> # => {5=>"five"}
>
> There's no nil on key 0 or 1 or 2...
>
> h[1]
> # => nil
>
> h.fetch(1)
>
> # It raises an exception!!!
>
> KeyError: key not found: 1
> from (irb):11:in `fetch'
> from (irb):11
> from /Users/abinoam/.rvm/rubies/ruby-2.1.0/bin/irb:11:in `<main>'
>
> > h.fetch(1) { "My Defaul Value" }
>
> # => "My Default Value"
>
> If you really need to use Array you can simply use an "or" like
>
> my_var = a[1] || "My Default Value"
>

Thanks Abinoam for your reply. I actually looking to create an Array, whose
default elements will be *different hash( means object_id should be different
)*. So that on runtime I can access any array element, and add key to the
hash, with a value.

Look the answer - ruby - Best way to check for nil and update hash value - Stack Overflow . The similar thing I am looking for an
array if can be implemented. If `Array#default=` exist, then all problem can
be solved, but it exist for Hash, not Array.

--

Regards,
Arup Rakshit

array =

def array.get(i)
  self[i] ||= {}
end

Alternatively

class <<array
  alias _get
  def (i) h=_get(i) or self[i] = {} end
end

irb(main):010:0> array[0][:foo]=:bar
=> :bar
irb(main):011:0> array[3][:bar]=:foo
=> :foo
irb(main):012:0> array
=> [{:foo=>:bar}, nil, nil, {:bar=>:foo}]

Cheers

robert

···

On Thu, May 15, 2014 at 6:06 PM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

Look the answer - ruby - Best way to check for nil and update hash value - Stack Overflow . The similar thing I am looking for an
array if can be implemented. If `Array#default=` exist, then all problem can
be solved, but it exist for Hash, not Array.

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

This is exquisite. :slight_smile:

···

On Tue, May 20, 2014 at 6:56 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

class <<array
  alias _get
  def (i) h=_get(i) or self[i] = {} end
end