Enumerable#unassociate

Have a look:

  module Enumerable

    # Take an associative array and unassociate it.

···

#
    # [[:a,1], [:b,2]].unassociate.to_a #=> [:a, [1], :b, [2]]
    # [[:a,1], [:b,2]].unassociate(1).to_a #=> [:a, 1, :b, 2]
    #
    def unassociate(index = 1..-1)
      return to_enum(:unassociate, index) unless block_given?

      each do |v|
        case v
        when Array
          yield v[0]
          yield v[index]
        else
          yield v
          yield nil
        end
      end
    end

  end

Is it a good method name? Is 1..-1 the best default?

Other thoughts/ suggestions?

What's the use case for this?

Kind regards

robert

···

On Mon, Jun 25, 2012 at 1:35 AM, Intransition <transfire@gmail.com> wrote:

Have a look:

module Enumerable

\# Take an associative array and unassociate it\.
\#
\#   \[\[:a,1\], \[:b,2\]\]\.unassociate\.to\_a     \#=&gt; \[:a, \[1\], :b, \[2\]\]
\#   \[\[:a,1\], \[:b,2\]\]\.unassociate\(1\)\.to\_a  \#=&gt; \[:a, 1, :b, 2\]
\#
def unassociate\(index = 1\.\.\-1\)

Other thoughts/ suggestions?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

In my case it's supplemental to another method I am working on. I have no
name for it yet, so call it #h.

  # Convert an Enumerable object to a Hash.

···

On Monday, June 25, 2012 2:38:48 AM UTC-4, Robert Klemme wrote:

What's the use case for this?

  #
  # [:a, 1, :b, 2].h
  # #=> {:a=>1, :b=>2}
  #
  # [:a, 1, :b, 2, :a, 3].h{ |v0,v1| v0.to_i + v1 }
  # #=> {:a=>4, :b=>2}
  #
  def h(init={})
    h = init

    if block_given?
      each_slice(2) do |k,v|
        h[k] = yield h[k], v
      end
    else
      each_slice(2){ |k,v| h[k] = v }
    end

    h
  end

The #unassociate method qould be of use as a preparation for using h, since
this doesn't work with associative arrays (like whats returned by
Hash#to_a).

  [[:a,1], [:b,2], [:a,3]].unassociate.h{ |v0, v1| v0 << v1 }
  #=> {:a=>[1,3], :b=>2}

What's the use case for this?

In my case it's supplemental to another method I am working on.

And what's the use case for *that* method?

I have no name for it yet, so call it #h.

# Convert an Enumerable object to a Hash.
#
# [:a, 1, :b, 2].h
# #=> {:a=>1, :b=>2}
#
# [:a, 1, :b, 2, :a, 3].h{ |v0,v1| v0.to_i + v1 }
# #=> {:a=>4, :b=>2}
#
def h(init={})
h = init

You never assign h nor init so you could completely get rid of h.
Btw, if you call the argument Hash "init" I would not necessarily
expect it to be modified. Maybe it's better to do

h = init.dup

Or, to save one instantiation

def h(init = nil)
  h = init ? init.dup : {}

if block\_given?
  each\_slice\(2\) do |k,v|
    h\[k\] = yield h\[k\], v

I find it strange that you yield h[k] and not k. The caller can never
know what k was, while if you pass k he can look up in init and obtain
the value you now yield.

  end
else
  each\_slice\(2\)\{ |k,v| h\[k\] = v \}
end

h

end

It's totally mysterious what you are after here. The fact that you do
not have a name yet might be indicative that this methods are probably
not such a good idea. They do not look generally useful to me.

Kind regards

robert

···

On Mon, Jun 25, 2012 at 4:59 PM, Intransition <transfire@gmail.com> wrote:

On Monday, June 25, 2012 2:38:48 AM UTC-4, Robert Klemme wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

And what's the use case for *that* method?

To convert an Enumerable to a Hash. Sorry, I should have specified that.

I have no name for it yet, so call it #h.

>
> # Convert an Enumerable object to a Hash.
> #
> # [:a, 1, :b, 2].h
> # #=> {:a=>1, :b=>2}
> #
> # [:a, 1, :b, 2, :a, 3].h{ |v0,v1| v0.to_i + v1 }
> # #=> {:a=>4, :b=>2}
> #
> def h(init={})
> h = init

You never assign h nor init so you could completely get rid of h.

??? What about `h[k] = v`, or am I misunderstanding?

Btw, if you call the argument Hash "init" I would not necessarily

expect it to be modified. Maybe it's better to do

h = init.dup

Or, to save one instantiation

def h(init = nil)
  h = init ? init.dup : {}

> if block_given?
> each_slice(2) do |k,v|
> h[k] = yield h[k], v

I find it strange that you yield h[k] and not k. The caller can never
know what k was, while if you pass k he can look up in init and obtain
the value you now yield.

The idea behind that is to allow Symbol#to_proc to be useful.

  a = [:a, 1, :b, 2, :a, 3]

  i = Hash.new{ |h,k| h[k] = }
  a.h(i, &:+) #=> {:a=>[1,3], :b=>[2]}

I considered other interfaces to the block but this one seemed like it
would be the most useful b/c of this.

It's totally mysterious what you are after here. The fact that you do

not have a name yet might be indicative that this methods are probably
not such a good idea. They do not look generally useful to me.

No, that's me simply not giving enough initial context, which sometimes I
do so not to skew others consideration. But not very helpful in the case,
clearly.

···

On Monday, June 25, 2012 12:00:01 PM UTC-4, Robert Klemme wrote:

I still don't see why that would be better. Both of your methods are
way too magical to be understandable.

This, while longer, at least makes sense.

a = [:a, 1, :b, 2, :a, 3]
Hash[ a.each_slice(2).group_by{|s,n| s}.map{|k,v| [k, v.map{|s,n| n}]
} ] #=> {:a=>[1,3], :b=>[2]}

-- Matma Rex

And what's the use case for *that* method?

To convert an Enumerable to a Hash. Sorry, I should have specified that.

But not only that: you need a Hash as input to do transformations
along the way. Wouldn't this be more reasonable if you just want to
convert to a Hash?

def to_hash
  {}.tap do |h|
    each_slice 2 do |k, v|
      k, v = yield k, v if block_given?
      h[k] = v
    end
  end
end

> def h(init={})
> h = init

You never assign h nor init so you could completely get rid of h.

??? What about `h[k] = v`, or am I misunderstanding?

Yes. There is just one assignment to h.

I find it strange that you yield h[k] and not k. The caller can never
know what k was, while if you pass k he can look up in init and obtain
the value you now yield.

The idea behind that is to allow Symbol#to_proc to be useful.

a = [:a, 1, :b, 2, :a, 3]

i = Hash.new{ |h,k| h[k] = }
a.h(i, &:+) #=> {:a=>[1,3], :b=>[2]}

irb(main):029:0> i = Hash.new{ |h,k| h[k] = }
=> {}
irb(main):030:0> a.each_slice(2){|k,v| i[k] << v}
=> nil
irb(main):031:0> i
=> {:a=>[1, 3], :b=>[2]}

I considered other interfaces to the block but this one seemed like it would
be the most useful b/c of this.

It's totally mysterious what you are after here. The fact that you do
not have a name yet might be indicative that this methods are probably
not such a good idea. They do not look generally useful to me.

No, that's me simply not giving enough initial context, which sometimes I
do so not to skew others consideration. But not very helpful in the case,
clearly.

I agree with Bartosz, there is a lot of magic in there and the method
does more than one thing which is always suspicious. If you want to
do a transformation a la #map along the way I would leave that
completely to a block passed and not restrict it to a Hash (well, a
Proc might work as well - but still).

Kind regards

robert

···

On Mon, Jun 25, 2012 at 9:57 PM, Intransition <transfire@gmail.com> wrote:

On Monday, June 25, 2012 12:00:01 PM UTC-4, Robert Klemme wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/