Array Practice

As some of you may know from previous threads im trying to practice
specific areas of ruby. One simple exercise i set myself was taking a
elements in an array such as

[1,2,3,1,2,2,4,3,2,1]

and then grouping them together and putting them in subarrays within an
array like this

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

Heres how i did it (im new to both programming and ruby)

def subpack(list)
  uniqlist = Array.new
  subpacklist = Array.new
  list.sort!

  uniqlist = list.uniq
  uniqlist.each_index do |i|
    rangeleft = list.index(uniqlist[i])
    rangeright = list.rindex(uniqlist[i])
    subpacklist << list.slice(rangeleft..rangeright)
  end
  subpacklist
end

WITHOUT GIVING ME YOUR SOLUTION IN FULL, how could i improve this...
i.e. give me some hints, the names of some methods but not the solution
as i want a go myself.

···

--
Posted via http://www.ruby-forum.com/.

Adam Akhtar wrote:
(...)

    rangeleft = list.index(uniqlist[i])
    rangeright = list.rindex(uniqlist[i])
    subpacklist << list.slice(rangeleft..rangeright)

I like the index/rindex trick. I have actualy done a similar job, going
through a big logfile to see which users were most active.
I opted for an array of hashes, with the frequency as value.
My result would have been:
[{1=>3},{2=>4},{3=>2},{4=>1}]
Can adapt your code to do the same?

···

--
Posted via http://www.ruby-forum.com/\.

Think about how you might do it with a pencil...
- write the values out in order "[ 1, 1, 1, 2, 2, 2, 2, 3, 3, 4 ]"
- if the "next" value is different from the last value processed (and initially there is no last value), then start a new sub-array with this single value (my pencil would insert a '[' between the '[' and '1')
- ...and if you'd already written a '[', you have to then write "],["
- if the next value is the same, move your pencil (since it goes in the current sub-array)
- when you run out of values, close the final subarray with ']'

It shouldn't take much to think about how this turns into Ruby (keeping in mind that Arrays are always finite so you don't really have to "write" the ']')

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On Feb 6, 2008, at 6:20 PM, Adam Akhtar wrote:

As some of you may know from previous threads im trying to practice
specific areas of ruby. One simple exercise i set myself was taking a
elements in an array such as

[1,2,3,1,2,2,4,3,2,1]

and then grouping them together and putting them in subarrays within an
array like this

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

Heres how i did it (im new to both programming and ruby)

def subpack(list)
uniqlist = Array.new
subpacklist = Array.new
list.sort!

uniqlist = list.uniq
uniqlist.each_index do |i|
   rangeleft = list.index(uniqlist[i])
   rangeright = list.rindex(uniqlist[i])
   subpacklist << list.slice(rangeleft..rangeright)
end
subpacklist
end

WITHOUT GIVING ME YOUR SOLUTION IN FULL, how could i improve this...
i.e. give me some hints, the names of some methods but not the solution
as i want a go myself.

Adam Akhtar wrote:

As some of you may know from previous threads im trying to practice
specific areas of ruby. One simple exercise i set myself was taking a
elements in an array such as

[1,2,3,1,2,2,4,3,2,1]

and then grouping them together and putting them in subarrays within an
array like this

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

Heres how i did it (im new to both programming and ruby)

def subpack(list)
  uniqlist = Array.new
  subpacklist = Array.new
  list.sort!

  uniqlist = list.uniq
  uniqlist.each_index do |i|
    rangeleft = list.index(uniqlist[i])
    rangeright = list.rindex(uniqlist[i])
    subpacklist << list.slice(rangeleft..rangeright)
  end
  subpacklist
end

WITHOUT GIVING ME YOUR SOLUTION IN FULL, how could i improve this...
i.e. give me some hints, the names of some methods but not the solution
as i want a go myself.

Another way would be to iterate over your original array and add each
number to a Hash as you go. A Hash keys will be one of the numbers,
and the corresponding value will be an array containing all of that
particular number.

You can create a new Hash so that when you access a non existent key in
a Hash an empty array will be returned. See the block form of
Hash.new().

Finally, you can create your final array from the hash values using
Hash#values.

···

--
Posted via http://www.ruby-forum.com/\.

My solution uses #uniq, #each, #<<, #select, and #==. Oh, and #

Todd

···

On Feb 6, 2008 5:20 PM, Adam Akhtar <adamtemporary@gmail.com> wrote:

As some of you may know from previous threads im trying to practice
specific areas of ruby. One simple exercise i set myself was taking a
elements in an array such as

[1,2,3,1,2,2,4,3,2,1]

and then grouping them together and putting them in subarrays within an
array like this

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

Heres how i did it (im new to both programming and ruby)

def subpack(list)
  uniqlist = Array.new
  subpacklist = Array.new
  list.sort!

  uniqlist = list.uniq
  uniqlist.each_index do |i|
    rangeleft = list.index(uniqlist[i])
    rangeright = list.rindex(uniqlist[i])
    subpacklist << list.slice(rangeleft..rangeright)
  end
  subpacklist
end

WITHOUT GIVING ME YOUR SOLUTION IN FULL, how could i improve this...
i.e. give me some hints, the names of some methods but not the solution
as i want a go myself.

The Array#assoc method is your friend here.

If you have questions or comments on this, please Cc: me directly as
well as sending to the list. (This should happen automatically if the
list doesn't wipe out my reply-to header.)

cjs

···

On 2008-02-07 08:20 +0900 (Thu), Adam Akhtar wrote:

[1,2,3,1,2,2,4,3,2,1]
and then grouping them together and putting them in subarrays within an
array like this
[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

--
Curt Sampson <cjs@starling-software.com> +81 90 7737 2974
Mobile sites and software consulting: http://www.starling-software.com

Anytime I want to "build up" something from an existing Enumerable
object (Array, etc.) in Ruby, I usually look to inject or collect; the
most elegant of the way I've come up with of doing exactly what you
want uses ==, *, uniq, collect, find_all, and size, and the function
body fits on a single line without semi-colons. (I'm not holding up
that it is a one-liner as a strength, just as a description.)

···

On Feb 6, 2008 3:20 PM, Adam Akhtar <adamtemporary@gmail.com> wrote:

As some of you may know from previous threads im trying to practice
specific areas of ruby. One simple exercise i set myself was taking a
elements in an array such as

[1,2,3,1,2,2,4,3,2,1]

and then grouping them together and putting them in subarrays within an
array like this

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

Heres how i did it (im new to both programming and ruby)

def subpack(list)
  uniqlist = Array.new
  subpacklist = Array.new
  list.sort!

  uniqlist = list.uniq
  uniqlist.each_index do |i|
    rangeleft = list.index(uniqlist[i])
    rangeright = list.rindex(uniqlist[i])
    subpacklist << list.slice(rangeleft..rangeright)
  end
  subpacklist
end

WITHOUT GIVING ME YOUR SOLUTION IN FULL, how could i improve this...
i.e. give me some hints, the names of some methods but not the solution
as i want a go myself.
--
Posted via http://www.ruby-forum.com/\.

irb(main):002:0> a=[1,2,3,1,2,2,4,3,2,1]
=> [1, 2, 3, 1, 2, 2, 4, 3, 2, 1]
irb(main):003:0> a.group_by{|x|x}
=> {1=>[1, 1, 1], 2=>[2, 2, 2, 2], 3=>[3, 3], 4=>[4]}
irb(main):004:0> a.group_by{|x|x}.values
=> [[1, 1, 1], [2, 2, 2, 2], [3, 3], [4]]

ruby1.9 though. i'm threading on 1.9 since it is fast, i mean really
fast, even on windows :slight_smile:
kind regards -botp

···

On Feb 7, 2008 7:20 AM, Adam Akhtar <adamtemporary@gmail.com> wrote:

As some of you may know from previous threads im trying to practice
specific areas of ruby. One simple exercise i set myself was taking a
elements in an array such as

[1,2,3,1,2,2,4,3,2,1]

and then grouping them together and putting them in subarrays within an
array like this

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

Well you know what, as i was thinking of a solution to this, hashes
popped into my head. I didnt know how they would be used but soemthing
whired and said you could probably do it with them. I always tend to shy
away from them but seeing as you laid down the challenge ill go away and
try and replicate your way. cheers!

In the meantime keep em coming!

···

--
Posted via http://www.ruby-forum.com/.

Siep Korteling wrote:
(...)

[{1=>3},{2=>4},{3=>2},{4=>1}]
Can adapt your code to do the same?

Sorry. This should read
{1=>3, 2=>4, 3=>2, 4=>1}
Can you adapt your code to do the same?

Maybe you'd have to read up on hashes before you planned to. I'm
learning the same way as you do. Getting some grip on Fixnum, String,
Array, Hash, File and Date enabled me to write better scripts then I did
with any other scripting language.

Regards,

Siep

···

--
Posted via http://www.ruby-forum.com/\.

Curt Sampson wrote:

···

On 2008-02-07 08:20 +0900 (Thu), Adam Akhtar wrote:

[1,2,3,1,2,2,4,3,2,1]
and then grouping them together and putting them in subarrays within an
array like this
[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

The Array#assoc method is your friend here.

Really? Where's the array containing arrays come from?

------------------------------------------------------------ Array#assoc
     array.assoc(obj) -> an_array or nil
------------------------------------------------------------------------
     Searches through an array whose elements are also arrays comparing obj with the first element of each contained array using obj.==. Returns the first contained array that matches (that is, the first associated array), or nil if no match is found. See also Array#rassoc.

Clifford Heath.

Oh, and uses .

···

On Feb 6, 2008 6:15 PM, Christopher Dicely <cmdicely@gmail.com> wrote:

Anytime I want to "build up" something from an existing Enumerable
object (Array, etc.) in Ruby, I usually look to inject or collect; the
most elegant of the way I've come up with of doing exactly what you
want uses ==, *, uniq, collect, find_all, and size, and the function
body fits on a single line without semi-colons. (I'm not holding up
that it is a one-liner as a strength, just as a description.)

On Feb 6, 2008 3:20 PM, Adam Akhtar <adamtemporary@gmail.com> wrote:

> As some of you may know from previous threads im trying to practice
> specific areas of ruby. One simple exercise i set myself was taking a
> elements in an array such as
>
> [1,2,3,1,2,2,4,3,2,1]
>
> and then grouping them together and putting them in subarrays within an
> array like this
>
> [ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]
>
> Heres how i did it (im new to both programming and ruby)
>
> def subpack(list)
> uniqlist = Array.new
> subpacklist = Array.new
> list.sort!
>
> uniqlist = list.uniq
> uniqlist.each_index do |i|
> rangeleft = list.index(uniqlist[i])
> rangeright = list.rindex(uniqlist[i])
> subpacklist << list.slice(rangeleft..rangeright)
> end
> subpacklist
> end
>
>
> WITHOUT GIVING ME YOUR SOLUTION IN FULL, how could i improve this...
> i.e. give me some hints, the names of some methods but not the solution
> as i want a go myself.
> --
> Posted via http://www.ruby-forum.com/\.
>
>

Hm. My function uses: inject, assoc, and, or, <<, [...]. The function
body fits easily on an 80 column line with one semicolon, if I shorten
the variable name "result" to "r".

cjs

···

On 2008-02-07 11:15 +0900 (Thu), Christopher Dicely wrote:

...the most elegant of the way I've come up with of doing exactly
what you want uses ==, *, uniq, collect, find_all, and size, and the
function body fits on a single line without semi-colons.

--
Curt Sampson <cjs@starling-software.com> +81 90 7737 2974
Mobile sites and software consulting: http://www.starling-software.com

Ruby 1.9 lets you do it with a few less methods... (I'll give it away because I'm fairly sure the OP won't be using 1.9). Of course, it only works on immediate values...

[1,2,3,1,2,2,4,3,2,1].group_by(&:object_id).values

Cheers

Dave

···

On Feb 6, 2008, at 8:15 PM, Christopher Dicely wrote:

Anytime I want to "build up" something from an existing Enumerable
object (Array, etc.) in Ruby, I usually look to inject or collect; the
most elegant of the way I've come up with of doing exactly what you
want uses ==, *, uniq, collect, find_all, and size, and the function
body fits on a single line without semi-colons. (I'm not holding up
that it is a one-liner as a strength, just as a description.)

Rob Biedenharn wrote:

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]
   rangeleft = list.index(uniqlist[i])
as i want a go myself.

Think about how you might do it with a pencil...
- write the values out in order "[ 1, 1, 1, 2, 2, 2, 2, 3, 3, 4 ]"
- if the "next" value is different from the last value processed (and
initially there is no last value), then start a new sub-array with
this single value (my pencil would insert a '[' between the '[' and '1')
- ...and if you'd already written a '[', you have to then write "],["
- if the next value is the same, move your pencil (since it goes in
the current sub-array)
- when you run out of values, close the final subarray with ']'

well heres my way of doing the above:-

def subpackarray passedlist

  orderedlist = passedlist.sort
  subgrouplist = Array.new
  orderedlist.each_index do |i|
    if ((i == 0) || (orderedlist[i] != orderedlist[i-1]))
      #create a new subgroup array and add the element.
      subgrouplist << Array.new
      subgrouplist.last.push orderedlist[i]
    else
      #add element to existing subgroup
      subgrouplist.last.push orderedlist[i]
    end
  end
  subgrouplist
end

i think thats the way he was intending it. Ill start figuring out the
others as well. Thanks so much for the posts. I think this makes great
practice asking for hints rather than just reading someone elses code.

···

On Feb 6, 2008, at 6:20 PM, Adam Akhtar wrote:

--
Posted via http://www.ruby-forum.com/\.

ahh cheers for that one as well rob...im on the case.

···

--
Posted via http://www.ruby-forum.com/.

Array#assoc searches an existing array of arrays; it doesn't build one.

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ].assoc(2) => [2,2,2,2]
[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ].assoc(5) => nil

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On Feb 6, 2008, at 8:30 PM, Clifford Heath wrote:

Curt Sampson wrote:

On 2008-02-07 08:20 +0900 (Thu), Adam Akhtar wrote:

[1,2,3,1,2,2,4,3,2,1]
and then grouping them together and putting them in subarrays within an
array like this
[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]

The Array#assoc method is your friend here.

Really? Where's the array containing arrays come from?

------------------------------------------------------------ Array#assoc
   array.assoc(obj) -> an_array or nil
------------------------------------------------------------------------
   Searches through an array whose elements are also arrays comparing obj with the first element of each contained array using obj.==. Returns the first contained array that matches (that is, the first associated array), or nil if no match is found. See also Array#rassoc.

Clifford Heath.

and with hashes

def subpack(passedlist)
  hsh = Hash.new
  subpacklist = []
  #create a hsh of element frequency
  passedlist.each do |element|
    hsh[element] = hsh[element].to_i + 1
  end

  hsh.each do |key, value|
    subgroup = Array.new
    value.times {subgroup.push(key)}
    subpacklist << subgroup
  end
  subpacklist
end

···

--
Posted via http://www.ruby-forum.com/.

one line (36 chars) with uniq, map, and select

···

On Feb 6, 2008 7:23 PM, Rob Biedenharn <Rob@agileconsultingllc.com> wrote:

On Feb 6, 2008, at 8:30 PM, Clifford Heath wrote:

> Curt Sampson wrote:
>> On 2008-02-07 08:20 +0900 (Thu), Adam Akhtar wrote:
>>> [1,2,3,1,2,2,4,3,2,1]
>>> and then grouping them together and putting them in subarrays
>>> within an
>>> array like this
>>> [ [1,1,1], [2,2,2,2] , [3,3] ,[4] ]
>> The Array#assoc method is your friend here.
>
> Really? Where's the array containing arrays come from?
>
> ------------------------------------------------------------
> Array#assoc
> array.assoc(obj) -> an_array or nil
> ------------------------------------------------------------------------
> Searches through an array whose elements are also arrays
> comparing obj with the first element of each contained array
> using obj.==. Returns the first contained array that matches
> (that is, the first associated array), or nil if no match is
> found. See also Array#rassoc.
>
> Clifford Heath.

Array#assoc searches an existing array of arrays; it doesn't build one.

[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ].assoc(2) => [2,2,2,2]
[ [1,1,1], [2,2,2,2] , [3,3] ,[4] ].assoc(5) => nil

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

a few people have mentioned some pretty concise solutions involving
map/collect selete find_all etc

can someone give me an example of such a solution using the above.

thanks

···

--
Posted via http://www.ruby-forum.com/.