0

I have an array of objects and want to build an unique array by the attribute "position", like

boxes.to_a.uniq! {|p| p[:position] }

but i want to distinguish before throwing all the doubles away, if the second attribute "mismatch" is equal or higher. For example i have:

{ position: 233, mismatch: 3},
{ position: 234, mismatch: 3},
{ position: 233, mismatch: 1}

and in the end i'd like to keep the one with less mismatch:

{ position: 234, mismatch: 3},
{ position: 233, mismatch: 1}

because position was the same in object 1 and 3, but mismatch was less in the last object.

Edit: boxes is an array of objects and i build it like that:

@boxes = []

...

@boxes << {
              :position => i,
              :mismatch => mm,
          }

where position and mismatch is calculated over a DNA sequence. The mismatch represents the hamming distance to a 9-nucleotide motif ( string like "TTGATGCTT" )

1
  • What is boxes originally? Hashes can't have duplicate keys anyways, so this is a bit confusing. Commented May 11, 2013 at 23:37

3 Answers 3

3

I'm not sure what these hashes represent, so you can probably think of better variable names.

Try:

boxes = [
  { position: 233, mismatch: 3},
  { position: 234, mismatch: 3},
  { position: 233, mismatch: 1},
]

boxes.group_by{ |box| box[:position] }
     .map{ |_, boxes| boxes.min_by{ |box| box[:mismatch] } }
#=> [{:position=>233, :mismatch=>1}, {:position=>234, :mismatch=>3}]
Sign up to request clarification or add additional context in comments.

Comments

0

Something like this:

new_boxes = {}

boxes.each do |box|
  pos = box[:position]
  if new_boxes[pos] && new_boxes[pos][:mismatch] > box[:mismatch]
    new_boxes[pos] = box
  end
end

boxes = new_boxes.values

Comments

0
boxes = [
  { position: 233, mismatch: 1},
  { position: 234, mismatch: 3},
  { position: 233, mismatch: 3},
  { position: 234, mismatch: 2}
]

boxes.sort_by{|x| x.values }
     .uniq{|y| y[:position]}

#=> [{:position=>233, :mismatch=>1}, {:position=>234, :mismatch=>2}]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.