[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

move to front of array

Payton Swick

12/21/2005 8:09:00 PM

Hi,

I have an array of Strings, and I'd like to find one of the items by
Regexp, then move that item to the front of the array, eg:

array = %w(a B c d Cool e f G)
array.unshift(array.slice!(array.index(array.find { |i| i =~ /cool/i
}))) if array.find { |i| i =~ /cool/i }

Better/cleaner/shorter ways to do it?

-Payton


18 Answers

Florian Frank

12/21/2005 8:29:00 PM

0

Payton Swick wrote:

> I have an array of Strings, and I'd like to find one of the items by
> Regexp, then move that item to the front of the array, eg:
>
> array = %w(a B c d Cool e f G)
> array.unshift(array.slice!(array.index(array.find { |i| i =~ /cool/i
> }))) if array.find { |i| i =~ /cool/i }


In 1.8.x:

require 'enumerator'
if f = array.enum_for(:each_index).find { |i| array[i] =~ /cool/i }
array.unshift array.delete_at(f)
end


In 1.9.x you can do:

array.unshift array.delete_at(array.index { |x| x =~ /cool/i })

--
Florian Frank



Jacob Fugal

12/21/2005 8:32:00 PM

0

On 12/21/05, Payton Swick <payton@foolord.com> wrote:
> Hi,
>
> I have an array of Strings, and I'd like to find one of the items by
> Regexp, then move that item to the front of the array, eg:
>
> array = %w(a B c d Cool e f G)
> array.unshift(array.slice!(array.index(array.find { |i| i =~ /cool/i
> }))) if array.find { |i| i =~ /cool/i }
>
> Better/cleaner/shorter ways to do it?
>
> -Payton

array = %w(a B c d Cool e f G)
if cool = array.find { |i| i =~ /cool/i }
array.delete(cool)
array.unshift(cool)
end

?

Jacob Fugal


Logan Capaldo

12/21/2005 8:34:00 PM

0


On Dec 21, 2005, at 3:08 PM, Payton Swick wrote:

> Hi,
>
> I have an array of Strings, and I'd like to find one of the items
> by Regexp, then move that item to the front of the array, eg:
>
> array = %w(a B c d Cool e f G)
> array.unshift(array.slice!(array.index(array.find { |i| i =~ /cool/
> i }))) if array.find { |i| i =~ /cool/i }
>
> Better/cleaner/shorter ways to do it?
>
> -Payton
>

I don't know about shorter but...

require 'enumerator'
array = %w(a B c d Cool e f G)
index = array.to_enum(:each_index).find { |i| array[i] =~ /cool/i }
array.unshift( array.delete_at( index ) )



Eero Saynatkari

12/21/2005 8:39:00 PM

0

Payton Swick wrote:
> Hi,
>
> I have an array of Strings, and I'd like to find one of the items by
> Regexp, then move that item to the front of the array, eg:
>
> array = %w(a B c d Cool e f G)
> array.unshift(array.slice!(array.index(array.find { |i| i =~ /cool/i
> }))) if array.find { |i| i =~ /cool/i }
>
> Better/cleaner/shorter ways to do it?

This should work (but without error checking):

array.unshift(array.delete(array.grep(/cool/i).first))

> -Payton


E


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


Dan Diebolt

12/21/2005 8:52:00 PM

0

Try this:

array1 = %w(a B c d Cool e f G)
array1.partition {|i| i =~ /cool/i}
array2=array1.partition {|i| i =~ /cool/i}
array2.flatten #or array2.flatten!

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail...

Ross Bamford

12/21/2005 9:03:00 PM

0

On Wed, 21 Dec 2005 20:08:34 -0000, Payton Swick <payton@foolord.com>
wrote:

> Hi,
>
> I have an array of Strings, and I'd like to find one of the items by
> Regexp, then move that item to the front of the array, eg:
>
> array = %w(a B c d Cool e f G)
> array.unshift(array.slice!(array.index(array.find { |i| i =~ /cool/i
> }))) if array.find { |i| i =~ /cool/i }
>
> Better/cleaner/shorter ways to do it?

Not sure about better or cleaner, but here's a couple of ideas:

Without error checking:

(ary - [t = ary.detect { |$_| ~/cool/i }]).unshift(t)

If you know there's only one of each element to start with, you could do:

(ary.unshift(ary.detect { |$_| ~/cool/i })).uniq

still without error checking, or:

ary.unshift(ti).uniq if ti = ary.detect { |$_| ~/cool/i }

To ensure you don't get a nil at the start, or

ary.unshift(*ti).uniq if ti = ary.grep(/cool/i)

to ensure you don't get flamed for using $_ ;)

Of course, if you have dupes to start with this won't work.

***
DISCLAIMER
***
I am not advocating the default input space, I don't think you should use
$_, it's only a few extra characters to do it the 'proper way', I just
wanted to go for brevity here.
***

:)

--
Ross Bamford - rosco@roscopeco.remove.co.uk

Ezra Zygmuntowicz

12/21/2005 9:13:00 PM

0


On Dec 21, 2005, at 12:08 PM, Payton Swick wrote:

> Hi,
>
> I have an array of Strings, and I'd like to find one of the items
> by Regexp, then move that item to the front of the array, eg:
>
> array = %w(a B c d Cool e f G)
> array.unshift(array.slice!(array.index(array.find { |i| i =~ /cool/
> i }))) if array.find { |i| i =~ /cool/i }
>
> Better/cleaner/shorter ways to do it?
>
> -Payton
>

array.unshift(array.delete_at(array.index("Cool")))

# => ["Cool", "a", "B", "c", "d", "e", "f", "G"]

-Ezra


Jacob Fugal

12/21/2005 9:15:00 PM

0

On 12/21/05, Dan Diebolt <dandiebolt@yahoo.com> wrote:
> Try this:
>
> array1 = %w(a B c d Cool e f G)
> array1.partition {|i| i =~ /cool/i}
> array2=array1.partition {|i| i =~ /cool/i}
> array2.flatten #or array2.flatten!

So something like:

array = %w(a B c d Cool e f G)
array = array.partition{ |el| el =~ /cool/i }.flatten

That certainly would work (assuming that only one element matches the
condition), and has a certain elegance. I wonder if there's a
significant performance penalty?

It also gave me this idea:

class Array
def bubble_up
score = lambda{ |a| (yield a) ? -1 : 1 }
self.sort_by { |a,b| score[a] <=> score[b] }
end

def bubble_up!( &proc )
self.replace(self.bubble_up( &proc ))
end
end

array = array.bubble_up! { |el| el =~ /cool/i }

Jacob Fugal


Daniel Berger

12/21/2005 9:16:00 PM

0


Jacob Fugal wrote:
> On 12/21/05, Payton Swick <payton@foolord.com> wrote:
> > Hi,
> >
> > I have an array of Strings, and I'd like to find one of the items by
> > Regexp, then move that item to the front of the array, eg:
> >
> > array = %w(a B c d Cool e f G)
> > array.unshift(array.slice!(array.index(array.find { |i| i =~ /cool/i
> > }))) if array.find { |i| i =~ /cool/i }
> >
> > Better/cleaner/shorter ways to do it?
> >
> > -Payton
>
> array = %w(a B c d Cool e f G)
> if cool = array.find { |i| i =~ /cool/i }
> array.delete(cool)
> array.unshift(cool)
> end

array.unshift(array.delete("Cool"))

Regards,

Dan

Ross Bamford

12/21/2005 9:32:00 PM

0

On Wed, 21 Dec 2005 21:13:11 -0000, Ezra Zygmuntowicz <ezmobius@gmail.com>
wrote:

> array.unshift(array.delete_at(array.index("Cool")))
>
> # => ["Cool", "a", "B", "c", "d", "e", "f", "G"]
>

Nice :) I missed 'index'. It led me to this:

([ary[ary.index("Cool")]] + ary).uniq

Then from there to

([*ary.grep(/Cool/)] + ary).uniq

Obviously it's useless line-noise and doesn't perform well I expect, but I
enjoy this game :)

--
Ross Bamford - rosco@roscopeco.remove.co.uk