question on the modification of the original object

Hello,

irb(main):022:0> class Array
irb(main):023:1> def mytest
irb(main):024:2> unshift(33)
irb(main):025:2> end
irb(main):026:1> end

irb(main):029:0> x=[3,2,1,4]
=> [3, 2, 1, 4]
irb(main):030:0> x.mytest
=> [33, 3, 2, 1, 4]
irb(main):031:0> x
=> [33, 3, 2, 1, 4]

What's the best way to avoid the original object (Array) to be modified in
the method?
What I think is:

copied = self
copied.unshift(33) # handle with this new array

But it's not that graceful IMO.

Thank you for the help.
Adriel

Here's two options:

class Array
  def mytest
    dup.unshift(33)
  end
end

class Array
  def mytest
    [33] + self
  end
end

x=[3,2,1,4] # => [3, 2, 1, 4]
x.mytest # => [33, 3, 2, 1, 4]
x # => [3, 2, 1, 4]

···

On 1/20/22, Adriel Peng <peng.adriel@gmail.com> wrote:

class Array; def mytest; unshift(33); end; end

x=[3,2,1,4] # => [3, 2, 1, 4]
x.mytest # => [33, 3, 2, 1, 4]
x # => [33, 3, 2, 1, 4]

... to avoid the original object (Array) to be modified in the method?

Thank you Frank. I like the dup way.

Now I finished the job, it's a simulation to Scala's fold function:

irb(main):040:0> class Array
irb(main):041:1> def fold(a)
irb(main):042:2> if block_given?
irb(main):043:3> dup.unshift(a).reduce {|x,y| yield(x,y)}
irb(main):044:3> else
irb(main):045:3> raise "no block"
irb(main):046:3> end
irb(main):047:2> end
irb(main):048:1> end
=> :fold
irb(main):049:0> [3,2,1,4].fold(10) {|x,y| x+y}
=> 20
irb(main):050:0> ["a","b","c"].fold("str:") {|x,y| x+y}
=> "str:abc"

Thanks

···

On Fri, Jan 21, 2022 at 10:31 AM Frank J. Cameron <fjc@fastmail.net> wrote:

On 1/20/22, Adriel Peng <peng.adriel@gmail.com> wrote:
> class Array; def mytest; unshift(33); end; end
>
> x=[3,2,1,4] # => [3, 2, 1, 4]
> x.mytest # => [33, 3, 2, 1, 4]
> x # => [33, 3, 2, 1, 4]
>
> ... to avoid the original object (Array) to be modified in the method?

Here's two options:

class Array
  def mytest
    dup.unshift(33)
  end
end

class Array
  def mytest
    [33] + self
  end
end

x=[3,2,1,4] # => [3, 2, 1, 4]
x.mytest # => [33, 3, 2, 1, 4]
x # => [3, 2, 1, 4]

Mutation in Ruby | Online Video Tutorial by thoughtbot
Dup vs Clone in Ruby: Understanding The Differences - RubyGuides

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Just for fun, I think every method in Ruby Array can be implemented by the
base map and reduce. The group_by is not easy to re-make, but with the
correct use of fold() and hash() it can be possible.

Here I implemented part of the methods that are available in scala/spark
but not in Ruby Array. :slight_smile:

class Array
    def reduceByKey
        if block_given?
            group_by {|x| x[0]}.map {|x,y| y.reduce {|x,y| [ x[0],
yield(x[1],y[1]) ]}}
        else
            raise "no block given"
        end
    end

    def mapValues
        if block_given?
            map {|x| [ x[0], yield(x[1]) ]}
        else
            raise "no block given"
        end
    end

   def countByKey
       group_by {|x| x[0]}.map {|x,y| [x,y.size]}
   end

    def fold(a)
        if block_given?
            dup.unshift(a).reduce {|x,y| yield(x,y)}
        else
            raise "no block given"
        end
    end
end

Here is the test code:

require '/path/to/module'

li = [["a",1],["b",2],["a",3],["b",5],["a",4],["c",9],["a",11]]

p li.mapValues {|s| s**2 }
p li.reduceByKey {|x,y| x+y }
p li.countByKey
p li.map {|x| x[1]}.fold(10) {|x,y| x+y}

Thanks for all the help.
Adriel

···

On Fri, Jan 21, 2022 at 10:41 AM Adriel Peng <peng.adriel@gmail.com> wrote:

Thank you Frank. I like the dup way.

Now I finished the job, it's a simulation to Scala's fold function:

irb(main):040:0> class Array
irb(main):041:1> def fold(a)
irb(main):042:2> if block_given?
irb(main):043:3> dup.unshift(a).reduce {|x,y| yield(x,y)}
irb(main):044:3> else
irb(main):045:3> raise "no block"
irb(main):046:3> end
irb(main):047:2> end
irb(main):048:1> end
=> :fold
irb(main):049:0> [3,2,1,4].fold(10) {|x,y| x+y}
=> 20
irb(main):050:0> ["a","b","c"].fold("str:") {|x,y| x+y}
=> "str:abc"

Thanks

On Fri, Jan 21, 2022 at 10:31 AM Frank J. Cameron <fjc@fastmail.net> > wrote:

On 1/20/22, Adriel Peng <peng.adriel@gmail.com> wrote:
> class Array; def mytest; unshift(33); end; end
>
> x=[3,2,1,4] # => [3, 2, 1, 4]
> x.mytest # => [33, 3, 2, 1, 4]
> x # => [33, 3, 2, 1, 4]
>
> ... to avoid the original object (Array) to be modified in the method?

Here's two options:

class Array
  def mytest
    dup.unshift(33)
  end
end

class Array
  def mytest
    [33] + self
  end
end

x=[3,2,1,4] # => [3, 2, 1, 4]
x.mytest # => [33, 3, 2, 1, 4]
x # => [3, 2, 1, 4]

Mutation in Ruby | Online Video Tutorial by thoughtbot
Dup vs Clone in Ruby: Understanding The Differences - RubyGuides

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;