# Newbie question

**URL:** <https://www.ruby-forum.com/t/newbie-question/94512>\
**Category:** Ruby\
**Created:** [May 5, 2006, 2:27pm UTC](https://www.ruby-forum.com/t/newbie-question/94512 "2006-05-05T14:27:21Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 2:27pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/1 "2006-05-05T14:27:21Z")

</div>

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”]

---

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 2:33pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/2 "2006-05-05T14:33:06Z")

</div>

2006/5/5, Kyle A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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

---

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 2:36pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/3 "2006-05-05T14:36:21Z")

</div>

On May 5, 2006, at 7:27 AM, Kyle A. 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 G. II

---

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 9:06pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/4 "2006-05-05T21:06:17Z")

</div>

James G. 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).

---

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 9:28pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/5 "2006-05-05T21:28:21Z")

</div>

Kyle A. 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…

---

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 9:52pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/6 "2006-05-05T21:52:51Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 10:11pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/7 "2006-05-05T22:11:31Z")

</div>

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”]

---

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 9:15pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/8 "2006-05-05T21:15:27Z")

</div>

On May 5, 2006, at 2:06 PM, Kyle A. 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 G. II

---

<div class="post-metadata">

**Author:** ![kalons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e480ec/32.png) [@kalons](https://www.ruby-forum.com/u/kalons)\
**Post date:** [May 5, 2006, 10:30pm UTC](https://www.ruby-forum.com/t/newbie-question/94512/9 "2006-05-05T22:30:15Z")

</div>

2006/5/5, Kyle A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> James G. 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
