PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.ruby > How to give depth to arrays?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
How to give depth to arrays?

Réponse
 
LinkBack Outils de la discussion
Vieux 22/11/2007, 05h24   #1
Chris Morales
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut How to give depth to arrays?

Hi,

I'm trying to convert an array like [2,3,3,5,4,4] in
[2,[3,3,[[5],4,4]]], but I really can't figure how to this.
Is there any way to achieve this in Ruby?

Thanks in advance.
--
Posted via http://www.ruby-forum.com/.

  Réponse avec citation
Vieux 22/11/2007, 06h21   #2
Shuaib Zahda
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

Chris Morales wrote:
> Hi,
>
> I'm trying to convert an array like [2,3,3,5,4,4] in
> [2,[3,3,[[5],4,4]]], but I really can't figure how to this.
> Is there any way to achieve this in Ruby?
>
> Thanks in advance.


I once asked a question about multidimensional arrays and I received a
solution like this


irb(main):001:0> array = []
=> []
irb(main):002:0> new_array = [1,2,3]
=> [1, 2, 3]
irb(main):003:0> array << new_array
=> [[1, 2, 3]]
irb(main):004:0> array << 3
=> [[1, 2, 3], 3]
irb(main):005:0> array[0] << 5
=> [1, 2, 3, 5]
irb(main):006:0> array
=> [[1, 2, 3, 5], 3]
irb(main):007:0> array[0] << [5]
=> [1, 2, 3, 5, [5]]
irb(main):008:0> array
=> [[1, 2, 3, 5, [5]], 3]
irb(main):009:0>


I wish this s
regards
--
Posted via http://www.ruby-forum.com/.

  Réponse avec citation
Vieux 22/11/2007, 07h38   #3
Peter Szinek
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

Chris Morales wrote:
> Hi,
>
> I'm trying to convert an array like [2,3,3,5,4,4] in
> [2,[3,3,[[5],4,4]]], but I really can't figure how to this.
> Is there any way to achieve this in Ruby?


I don't really get the question... do you want to do this automatically?
If yes, how should the mapping look like (i.e. what decides that 3 is 1
level deep, 5 is 4 level deep etc.)?

Cheers,
Peter
___
http://www.rubyrailways.com
http://scrubyt.org



  Réponse avec citation
Vieux 22/11/2007, 08h06   #4
Chris Morales
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

> I don't really get the question... do you want to do this automatically?
> If yes, how should the mapping look like (i.e. what decides that 3 is 1
> level deep, 5 is 4 level deep etc.)?


Sorry, my question was missing some important details.
1/ it's array of numbers only
2/ the first number is the base depth
3/ for every number increase a depth of array is added
so [1,2,4,2] => [1,[2,[[4]],2]]
and [5,5,6] => [5,5,[6]]
4/ and it would be wonderful if it were automatic, by extending the
Array class if possible. The image is a kind of opposite of flatten.

for now I'm trying with the insert/slice! couple, no cute at all & not
really working

class Array
def depthen
base_depth = self[0]
range = [0,0]
in_flag, out_flag = false, false
self.each_index{ |i|
if self[i]>base_depth && !in_flag
in_flag = true;
range[0] = i
end
if self[i] <= base_depth && !out_flag
out_flag = true
range[1] = i-1
end
}
self.insert(range[0], self.slice!(eval(range.join('..'))) )
end
end

p [2,3,3,5,4,4].depthen => [2,[3,3,5,4,4]]

I hope I'm on the good way, but the code is *really* ugly

Thank you in advance,
Chris.
--
Posted via http://www.ruby-forum.com/.

  Réponse avec citation
Vieux 22/11/2007, 09h28   #5
Chris Morales
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

Okay, I made it kinda works, clunky and ugly though...


class Array
def max
max = 0;
self.each{ |i| max = i>max ? i : max }
max
end
def min
min = 9999;
self.each{ |i| min = i<min ? i : min }
min
end
def depthen
base_depth = self.min
range = [0,0]
in_flag, out_flag = false, false
self.each_index{ |i|
if self[i]>base_depth && !in_flag
in_flag = true;
range[0] = i
end
if self[i] <= base_depth && !out_flag
out_flag = true
range[1] = i-1
end
}
to_insert = self.slice!(eval(range.join('..')))
to_insert.depthen if to_insert.max>to_insert.min
self.insert( range[0], to_insert )
end
end

p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]]

I will be really thankful if anybody could me improve this monster
with nice ruby tricks.

Thank you in advance,
Chris.
--
Posted via http://www.ruby-forum.com/.

  Réponse avec citation
Vieux 22/11/2007, 14h03   #6
Jesús Gabriel y Galán
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

On Nov 22, 2007 10:28 AM, Chris Morales <primo.tertio@gmail.com> wrote:
> Okay, I made it kinda works, clunky and ugly though...
>
>
> class Array
> def max
> max = 0;
> self.each{ |i| max = i>max ? i : max }
> max
> end
> def min
> min = 9999;
> self.each{ |i| min = i<min ? i : min }
> min
> end
> def depthen
> base_depth = self.min
> range = [0,0]
> in_flag, out_flag = false, false
> self.each_index{ |i|
> if self[i]>base_depth && !in_flag
> in_flag = true;
> range[0] = i
> end
> if self[i] <= base_depth && !out_flag
> out_flag = true
> range[1] = i-1
> end
> }
> to_insert = self.slice!(eval(range.join('..')))
> to_insert.depthen if to_insert.max>to_insert.min
> self.insert( range[0], to_insert )
> end
> end
>
> p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]]
>
> I will be really thankful if anybody could me improve this monster
> with nice ruby tricks.


With your code:

[2,3,5,3].depthen # => [2, [3, [[5], 3]]]

Shouldn't this be:

[2, [3, [[5]], 3]]

?

I'm trying to think of an elegant solution, but I'm kind of slow today...

Jesus.

  Réponse avec citation
Vieux 22/11/2007, 16h48   #7
Jesús Gabriel y Galán
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

On Nov 22, 2007 3:03 PM, Jes=FAs Gabriel y Gal=E1n <jgabrielygalan@gmail.co=
m> wrote:
> On Nov 22, 2007 10:28 AM, Chris Morales <primo.tertio@gmail.com> wrote:
> > p [2,3,3,5,4,4].depthen =3D> [2,[3,3,[[5],4,4]]]
> >
> > I will be really thankful if anybody could me improve this monster
> > with nice ruby tricks.

>
>
> With your code:
>
> [2,3,5,3].depthen # =3D> [2, [3, [[5], 3]]]
>
> Shouldn't this be:
>
> [2, [3, [[5]], 3]]
>
> ?
>
> I'm trying to think of an elegant solution, but I'm kind of slow today...


I managed to get some time at work and this is my first try,
I use a stack to maintain the arrays for each level when you are
going upwards, so you can add to the same array when you go
downwards (makes any sense?):

class Array
def depthen
depth =3D self[0]
result =3D []
stack =3D []
current =3D result
each do |x|
case depth <=3D> x
when 0
current << x
when -1
diff =3D x - depth
value =3D [x]
tmp =3D value
(diff - 1).times do
value =3D [value]
stack.push value
end
current << value
current =3D tmp
stack.push current
when 1
diff =3D depth - x + 1
diff.times {current =3D stack.pop}
current =3D result if current.nil?
current << x
end
depth =3D x
end
result
end
end


a =3D [[2,3,3,4,5,4,4], [2,3,5,3, 2]]
a.each {|x| p x.depthen}


[2, [3, 3, [4, [5], 4, 4]]]
[2, [3, [[5]], 3], 2]


Have fun,

Jesus.

  Réponse avec citation
Vieux 22/11/2007, 18h28   #8
Eric I.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

Others, including Chris Morales, have interpreted the task as follows:

> p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]]


But that doesn't seem right to me, since the element 2 is at a depth
of 1 and not 2. I would think the result should be:

[[2,[3,3,[[5],4,4]]]]

Anyway, here's a solution which handles my interpretation:

class Array
def depthen
result = []

self.each do |depth|
array_end = result
(depth - 1).times do
array_end << [] unless array_end.last.kind_of? Array
array_end = array_end.last
end
array_end << depth
end

result
end
end

And here's what it does:

p [2, 3, 3, 5, 4, 1, 4, 6, 10, 2].depthen
# => [[2, [3, 3, [[5], 4]]], 1, [[[4, [[6, [[[[10]]]]]]]], 2]]

To change it to the other interpretation, just change "depth - 1" to
"depth - 2". And then, presumably, the array depthen is called on
shouldn't have any "1"s in it (although even they're handled
"gracefully" with the depthen method provided).

Eric

====

Are you interested in on-site Ruby training that uses well-designed,
real-world, hands-on exercises? http://LearnRuby.com
  Réponse avec citation
Vieux 22/11/2007, 18h39   #9
Sebastian Hungerecker
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

Eric I. wrote:
> Others, including Chris Morales, have interpreted the task as follows:
> > p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]]

>
> But that doesn't seem right to me, since the element 2 is at a depth
> of 1 and not 2.


quoth Chris Morales:
>>>> the first number is the base depth



--
NP: Moonsorrow - 1065: Aika
Jabber: sepp2k@jabber.org
ICQ: 205544826

  Réponse avec citation
Vieux 22/11/2007, 18h46   #10
Eric I.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

On Nov 22, 1:39 pm, Sebastian Hungerecker <sep...@googlemail.com>
wrote:
> quoth Chris Morales:
>
> >>>> the first number is the base depth


Thank you, Sebastian! I lost track of that.

OK, here we go, then:

class Array
def depthen
base_depth = first
result = []

each do |depth|
array_end = result
(depth - base_depth).times do
array_end << [] unless array_end.last.kind_of? Array
array_end = array_end.last
end
array_end << depth
end

result
end
end

Eric

====

Interested in hands-on, on-site Ruby training? See http://LearnRuby.com
for information about a well-reviewed class.
  Réponse avec citation
Vieux 22/11/2007, 18h59   #11
Jesús Gabriel y Galán
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

On Nov 22, 2007 7:39 PM, Sebastian Hungerecker <sepp2k@googlemail.com> wrote:
> Eric I. wrote:
> > Others, including Chris Morales, have interpreted the task as follows:
> > > p [2,3,3,5,4,4].depthen => [2,[3,3,[[5],4,4]]]

> >
> > But that doesn't seem right to me, since the element 2 is at a depth
> > of 1 and not 2.

>
> quoth Chris Morales:
>
> >>>> the first number is the base depth


Yes, that's what I based my solution on. Afterwards I saw in his
solution that he used the min of the array which makes more sense...

Jesus.

  Réponse avec citation
Vieux 23/11/2007, 22h32   #12
Giles Bowkett
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

> I will be really thankful if anybody could me improve this monster
> with nice ruby tricks.


My first impression is that the code should probably achieve its goals
in some other way than it's currently attempting. Trying something
this intricate often means setting yourself up for failure. It might
be possible to use trees or something similar instead, depending on
the nature of the problem you've decided to solve.

--
Giles Bowkett

Podcast: http://hollywoodgrit.blogspot.com
Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com

  Réponse avec citation
Vieux 25/11/2007, 23h39   #13
Chris Morales
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to give depth to arrays?

Wow!
Thanks everybody & Thank you so much Eric

> class Array
> def depthen
> base_depth = first
> result = []
>
> each do |depth|
> array_end = result
> (depth - base_depth).times do
> array_end << [] unless array_end.last.kind_of? Array
> array_end = array_end.last
> end
> array_end << depth
> end
>
> result
> end
> end


I couldn't have dreamt a shorter way to achieve this, You really are a
Genius.
So short and nice! This must be what they call the ruby way I think

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

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 18h28.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,20969 seconds with 21 queries