0

Im struggling trying to remove some duplicates from an array. I have a spec which requires I do not not use inbuilt sorting & de-duplication methods... so .uniq .sort etc. Are out of use...

Here is my array ...

array = [1, "fred", 6, 5, "fred", "john", 6, "peter", "fred"]

I need it to output...

sorted_array = [1, 6, 5, "fred", "john", "peter"]

So far I have tried to use a Set as well as array & array however that outputs in the wrong order. I need the integers to occur in the list before the strings...

I have also tried to iterate through, finding if an element occurs more than once and using .delete & .delete_at however I can't figure out how to delete the second/third/fourth occurring element...

4 Answers 4

1

I don't know which built-in methods you can't use, but if you can use Array#| it's hard to imagine anything simpler than

array | []
  #=> [1, "fred", 6, 5, "john", "peter"]

Note this retains the ordering of array.

array & array works as well.

Sign up to request clarification or add additional context in comments.

Comments

0

Creating and returning a secondary cleaned array makes this fairly simple: iterate over the original array and append only those elements that do not already exist within the cleaned array:

def clean(array)
  cleaned = []
  array.each do |element|
    cleaned << element  if not cleaned.include?(element)
  end
  return cleaned
end

This is relatively quick and does exactly what you want.

Proof of concept (irb):

2.2.2 :001 > def clean(array); cleaned=[];  array.each{|ele| cleaned << ele  if not cleaned.include? ele}; cleaned; end
 => :clean

2.2.2 :002 > clean [1, "fred", 6, 5, "fred", "john", 6, "peter", "fred"]
 => [1, "fred", 6, 5, "john", "peter"]

You could improve processing times on large arrays by using a Hash instead. This would work by appending elements as keys to improve the internal lookup times, and then simply return a list of its keys for your array. (Caveat: doing this may return them in an arbitrary order, however, so further effort may be required to maintain the original order.)

Edit: I missed the sorting requirement in your expected output. Apologies.

1 Comment

No worries! :) I had this same method at one point! It's always the sorting that catches me out! :)
0

Building on what @terra did:

def uniq(array)
  uniq = []
  array.each do |element|
    uniq << element unless uniq.include?(element)
  end
  uniq
end

def sort(array)
  sorted = []
  [Integer, String].each do |type|
    sorted += array.select { |element| element.is_a? type }
  end
  sorted
end

So now if you do this:

p uniq_and_sorted = sort(uniq([1, "fred", 6, 5, "fred", "john", 6, "peter", "fred"]))

You should get:

[1, 6, 5, "fred", "john", "peter"]

Comments

0

This maybe long winded, but it works:

    array = [1, "fred", 6, 5, "fred", "john", 6, "peter", "fred"]

    numbers_array = []
    array.each do |e|
      numbers_array << e if e == e.to_i
    end

    numbers_array.sort!

    strings_array = []
    array.each do |e|
        strings_array << e if e == e.to_s
    end

    strings_array.sort!

    final_array = []
    final_array << numbers_array << strings_array
    final_array.flatten!
    final_array.uniq!

    p final_array

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.