Forum: Ruby Newbie question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
A1ab41fa0b9edd995f743b108d479671?d=identicon&s=25 Kyle Alons (kalons)
on 2006-05-05 14:27
Given an array like

["&abc", "a&cb", "b&ac", "ccc", "cb&a"]

what is the Ruby way to construct an array containing only elements with
duplicate characters following the &'s?  In this case

["&abc", "b&ac", "cb&a"]
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2006-05-05 14:33
(Received via mailing list)
2006/5/5, Kyle Alons <kalons@yahoo.com>:
> Given an array like
>
> ["&abc", "a&cb", "b&ac", "ccc", "cb&a"]
>
> what is the Ruby way to construct an array containing only elements with
> duplicate characters following the &'s?  In this case
>
> ["&abc", "b&ac", "cb&a"]

You can use select or inject. However it's not clear to me what you
mean by "duplicate characters following the &'s". Can you elaborate?

robert
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-05 14:36
(Received via mailing list)
On May 5, 2006, at 7:27 AM, Kyle Alons wrote:

> Given an array like
>
> ["&abc", "a&cb", "b&ac", "ccc", "cb&a"]
>
> what is the Ruby way to construct an array containing only elements
> with
> duplicate characters following the &'s?  In this case
>
> ["&abc", "b&ac", "cb&a"]

 >> ["&abc", "a&cb", "b&ac", "ccc", "cb&a"].grep(/&../)
=> ["&abc", "a&cb", "b&ac"]

Hope that helps.

James Edward Gray II
A1ab41fa0b9edd995f743b108d479671?d=identicon&s=25 Kyle Alons (kalons)
on 2006-05-05 21:06
James Gray wrote:
>  >> ["&abc", "a&cb", "b&ac", "ccc", "cb&a"].grep(/&../)
> => ["&abc", "a&cb", "b&ac"]
>
> Hope that helps.

That's not quite it.  That seems to match all strings containing an
ampersand followed by 2 other characters.  What I need is all strings
that have duplicate characters following an & (&a in the above).
Something a little more concrete:

["&File", "&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites", "&Help"]

would return

["&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites"]

(&e and &r are found multiple times).
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-05 21:15
(Received via mailing list)
On May 5, 2006, at 2:06 PM, Kyle Alons wrote:

>
> ["&File", "&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites",
> "&Help"]
>
> would return
>
> ["&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites"]
>
> (&e and &r are found multiple times).

No letters are duplicated in "&Edit".

I clearly don't understand your goal, but you solve it like this:

array_of_strings.select do |string|
   # put test against string here...
end

Sorry I am not more help.

James Edward Gray II
Ad7805c9fcc1f13efc6ed11251a6c4d2?d=identicon&s=25 Alex Young (Guest)
on 2006-05-05 21:28
(Received via mailing list)
Kyle Alons wrote:
> that have duplicate characters following an & (&a in the above).
> Something a little more concrete:
>
> ["&File", "&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites", "&Help"]
>
> would return
>
> ["&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites"]
>
> (&e and &r are found multiple times).
>

keys = {}

["&File", "&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites",
"&Help"].each do |l|
   l =~ /&(.)/
   (keys[ $1.downcase ] ||= []) << l
end

keys.values.select{|l| l.length > 1}.flatten

There's almost certainly a better way...
81d609425e306219d54d793a0ad98bce?d=identicon&s=25 Matthew Moss (Guest)
on 2006-05-05 21:52
(Received via mailing list)
What he's saying is that he wants both "&Edit" and "Vi&ew" to show up
because both have an 'e' after the ampersand.

I take it these are identifiers for Windows menus or the like, so the
character after the ampersand has to be unique within a particular
set.
81d609425e306219d54d793a0ad98bce?d=identicon&s=25 Matthew Moss (Guest)
on 2006-05-05 22:11
(Received via mailing list)
Here's a quick attempt:

x = ["&Edit", "P&roject", "Noamp", "Vi&ew", "S&ample", "T&ree"]
y = Hash.new { |h,k| h[k] = Array.new }

x.each do |s|
   if m = /&(.)/.match(s)
      y[m[1].downcase] << s
   end
end

y.values.select { |v| v.size > 1 }.flatten


=> ["&Edit", "Vi&ew", "P&roject", "T&ree"]
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2006-05-05 22:30
(Received via mailing list)
2006/5/5, Kyle Alons <kalons@yahoo.com>:
> James Gray wrote:
> >  >> ["&abc", "a&cb", "b&ac", "ccc", "cb&a"].grep(/&../)
> > => ["&abc", "a&cb", "b&ac"]
> >
> > Hope that helps.
>
> That's not quite it.  That seems to match all strings containing an
> ampersand followed by 2 other characters.  What I need is all strings
> that have duplicate characters following an & (&a in the above).

By your definition "a&cb" does not belong into the result set.

> Something a little more concrete:
>
> ["&File", "&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites", "&Help"]
>
> would return
>
> ["&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites"]
>
> (&e and &r are found multiple times).

Just for the fun of it:

irb(main):037:0> a=["&File", "&Edit", "Vi&ew", "P&roject", "T&ree",
"Favo&rites", "&Help"]
=> ["&File", "&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites",
"&Help"]

irb(main):038:0> a.inject(Hash.new {|h,k| h[k]=[]}) do |h,str|
irb(main):039:1*   /&(.)/ =~ str and h[$1.downcase[0]] << str
irb(main):040:1>   h
irb(main):041:1> end.values.select {|v| v.size > 1}.flatten
=> ["&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites"]

irb(main):042:0> a.inject(Hash.new {|h,k| h[k]=[]}) do |h,str|
irb(main):043:1*   /&(.)/ =~ str and h[$1.downcase[0]] << str
irb(main):044:1>   h
irb(main):045:1> end.inject([]){|res,(k,v)| res.concat v if v.size >
1;res }
=> ["&Edit", "Vi&ew", "P&roject", "T&ree", "Favo&rites"]

Did I mention that inject is great?

:-))

robert
This topic is locked and can not be replied to.