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 > compact or uniq that takes a block like sort?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
compact or uniq that takes a block like sort?

Réponse
 
LinkBack Outils de la discussion
Vieux 07/01/2008, 11h55   #1
Bil Kleb
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut compact or uniq that takes a block like sort?

Hi,

I'm looking for an elegant way to do the following:

Given an sorted array of (X,Y) pairs where Y is strictly
increasing, i.e., no repeated Ys.

Compact pairs with repeated Xs, keeping the pair with
the highest Y value.

E.g.,

require 'test/unit'

class TestConsolidation < Test::Unit::TestCase
def test_should_remove_repeated_Xs_but_save_one_with_h ighest_Y
initial = [ [ 1, 12 ], [ 3, 15 ], [ 3, 17 ], [ 3, 22 ], [ 7, 45 ] ]
desired = [ [ 1, 12 ], [ 3, 22 ], [ 7, 45 ] ]
assert_equal desired, initial.consolidate
end
end

class Array
def consolidate
# Too embarrassed to show current hack.
end
end

My least surprise inclination had me researching #uniq and #compact
to see if they took a block like #sort.

Thanks,
--
Bil Kleb
http://fun3d.larc.nasa.gov
  Réponse avec citation
Vieux 07/01/2008, 12h15   #2
Pit Capitain
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: compact or uniq that takes a block like sort?

2008/1/7, Bil Kleb <Bil.Kleb@nasa.gov>:
> I'm looking for an elegant way to do the following:
> (...)


Bil, this makes the test pass:

class Array
def consolidate
Hash[*flatten].sort
end
end

Regards,
Pit

  Réponse avec citation
Vieux 07/01/2008, 15h45   #3
Robert Klemme
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: compact or uniq that takes a block like sort?

2008/1/7, Bil Kleb <Bil.Kleb@nasa.gov>:
> Hi,
>
> I'm looking for an elegant way to do the following:
>
> Given an sorted array of (X,Y) pairs where Y is strictly
> increasing, i.e., no repeated Ys.
>
> Compact pairs with repeated Xs, keeping the pair with
> the highest Y value.
>
> E.g.,
>
> require 'test/unit'
>
> class TestConsolidation < Test::Unit::TestCase
> def test_should_remove_repeated_Xs_but_save_one_with_h ighest_Y
> initial = [ [ 1, 12 ], [ 3, 15 ], [ 3, 17 ], [ 3, 22 ], [ 7, 45 ] ]
> desired = [ [ 1, 12 ], [ 3, 22 ], [ 7, 45 ] ]
> assert_equal desired, initial.consolidate
> end
> end
>
> class Array
> def consolidate
> # Too embarrassed to show current hack.
> end
> end
>
> My least surprise inclination had me researching #uniq and #compact
> to see if they took a block like #sort.


This is easy with #inject:

ar.inject([]) do |res, (x,y)|
if res.empty? || res.last[0] != x
res << [x,y]
else
res.last[1] = y
end
res
end

Cheers

robert

--
use.inject do |as, often| as.you_can - without end

  Réponse avec citation
Vieux 07/01/2008, 17h20   #4
Joel VanderWerf
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: compact or uniq that takes a block like sort?

Pit Capitain wrote:
> 2008/1/7, Bil Kleb <Bil.Kleb@nasa.gov>:
>> I'm looking for an elegant way to do the following:
>> (...)

>
> Bil, this makes the test pass:
>
> class Array
> def consolidate
> Hash[*flatten].sort
> end
> end


That certainly is elegant!

Maybe Bil wanted to preserve the monotonicity?

class Array
def consolidate
Hash[*flatten].sort_by {|x,y| y}
end
end

p [ [5,1] , [3,2] ].consolidate # ==> [[5, 1], [3, 2]]

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

  Réponse avec citation
Vieux 07/01/2008, 17h53   #5
Daniel Finnie
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: compact or uniq that takes a block like sort?

A more general solution:

require 'set'

class Array
def uniq(&blk)
blk ||= lambda {|x| x}
already_seen = Set.new
uniq_array = []

self.each_with_index do |value, i|
x = blk.call(value)
unless already_seen.include? x
already_seen << x
uniq_array << value
end
end
uniq_array
end
end

and

class Array
def consolidate
reverse.uniq {|a| a.first}.reverse
end
end

Of course, the value that you keep for uniq is kinda arbitrary.

Dan
- Hide quoted text -

On 1/7/08, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:
> Pit Capitain wrote:
> > 2008/1/7, Bil Kleb <Bil.Kleb@nasa.gov>:
> >> I'm looking for an elegant way to do the following:
> >> (...)

> >
> > Bil, this makes the test pass:
> >
> > class Array
> > def consolidate
> > Hash[*flatten].sort
> > end
> > end

>
> That certainly is elegant!
>
> Maybe Bil wanted to preserve the monotonicity?
>
> class Array
> def consolidate
> Hash[*flatten].sort_by {|x,y| y}
> end
> end
>
> p [ [5,1] , [3,2] ].consolidate # ==> [[5, 1], [3, 2]]
>
> --
> vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
>
>


  Réponse avec citation
Vieux 12/01/2008, 16h10   #6
Bil
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: compact or uniq that takes a block like sort?

On Jan 7, 10:45 am, Robert Klemme <shortcut...@googlemail.com> wrote:
>
> This is easy with #inject:


Hey, thanks everyone for the !

I would have replied sooner, but my USENET feed dropped your replies
and I only now thought to look at groups.google.com.

Thanks again,
--
http://twitter.com/bil_kleb
  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 07h16.


É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,13169 seconds with 14 queries