2015-11-13 4 views
-1

Я добавил свой собственный метод к классу Array, который делает то же самое, что и Array # uniq.Monkey Patching Arrays в Ruby

Это моя версия:

arr = ["fun", "sun", 3, 5, 5, 5, 1, 2, 1, "fun"] 

class Array 
    def my_uniq 
     new_arr = [] 
     each do |item| 
      new_arr << item unless new_arr.include?(item) 
     end 
     new_arr 
    end 
end 

print arr.my_uniq 

Есть ли способ, чтобы изменить это, чтобы вернуть показатели уникальных элементов, а не самих элементов?

+0

Я предлагаю вам редактировать свой вопрос. 1. Определение вашего метода для 'my_uniq' не имеет значения, поэтому удалите его (Извините.) 2. Замените второе предложение на что-то более точное, например:« Как я могу написать метод «Массив», который возвращает (самый маленький) индекс каждого уникального элемента массива? " (Жирный шрифт не нужен.) 3. Удалите третье предложение. (К сожалению, никто не заботится.). 4. Приведите пример, который сохранит ваш вход ('arr = [" fun ", ...]') и предоставит желаемый или ожидаемый результат ('[0, 1, 2, 3, 6, 7]', если мое понимание верно). –

+0

Когда вы приводите пример, полезно назначить переменную для каждого входа, как вы это сделали ('arr = ....'). Таким образом, читатели могут ссылаться на эти переменные в ответах и ​​комментариях, не определяя их. Наконец, соглашение Ruby должно использовать snake_case для имен переменных и методов (например, 'new_arr', а не' newArr'). Вам не обязательно это делать, но если вы этого не сделаете, будьте осторожны, читатели вашего кода могут предположить, что вы новичок. –

+0

Спасибо за советы. Я буду обновлять и читать в стиле Ruby. – Thrynn

ответ

0

each_with_index позволит вам перебирать массив и возвращать индексы.

each_with_index do |item, index| 
    newArr << index unless newArr.include?(item) 
end 
0
class Array 
    def indices_uniq 
    uniq.map { |e| index(e) } 
    end 
end 

arr = ["fun", "sun", 3, 5, 5, 5, 1, 2, 1, "fun"] 
arr.indices_uniq 
    #=> [0, 1, 2, 3, 6, 7] 

Чтобы посмотреть, что здесь происходит, давайте напишем это более пространно и включают в себя код для отображения промежуточных значений:

class Array 
    def indices_uniq 
    puts "self = #{self}" 
    arr = self 
    u = arr.uniq 
    puts "u = #{u}" 
    u.map { |e| 
     puts "#{e} is at index #{index(e)}" 
     arr.index(e) } 
    end 
end 

arr.indices_uniq 
    # self = ["fun", "sun", 3, 5, 5, 5, 1, 2, 1, "fun"] 
    # u = ["fun", "sun", 3, 5, 1, 2] 
    # fun is at index 0 
    # sun is at index 1 
    # 3 is at index 2 
    # 5 is at index 3 
    # 1 is at index 6 
    # 2 is at index 7 
    #=> [0, 1, 2, 3, 6, 7] 

Мы можем заменить из u и arr:

class Array 
    def indices_uniq 
    self.uniq.map { |e| self.index(e) } 
    end 
end 

arr.indices_uniq 
    #=> [0, 1, 2, 3, 6, 7] 

Ключ: self является приемник для методов, которые не имеют явных приемников. В последней версии методов uniq и include оба имеют явный приемник self. Отсюда следует, что если явный приемник удаляется, приемник все равно будет self:

class Array 
    def indices_uniq 
    uniq.map { |e| index(e) } 
    end 
end 

arr.indices_uniq 
    #=> [0, 1, 2, 3, 6, 7] 

Другим способом сделать это, чтобы изменить оперативную линию:

map { |e| index(e) }.uniq