Добавить элемент в массив, если он уже не существует

У меня есть класс Ruby

class MyClass
  attr_writer :item1, :item2
end

my_array = get_array_of_my_class() #my_array is an array of MyClass
unique_array_of_item1 = []

Я хочу нажать MyClass#item1 на unique_array_of_item1, но только если unique_array_of_item1 еще не содержит этого item1. Существует простое решение, которое я знаю: просто перейдите через my_array и проверьте, содержит ли unique_array_of_item1 текущий item1 или нет.

Есть ли более эффективное решение?

Ответ 1

Вы можете использовать Set вместо Array.

Ответ 2

У @Coorasse есть хороший ответ, хотя так и должно быть:

my_array | [item]

И обновить my_array на месте:

my_array |= [item]

Ответ 3

Вам не нужно вручную перебирать my_array.

my_array.push(item1) unless my_array.include?(item1)

Edit:

Как указывает Томбарт в своем комментарии, использование Array#include? не очень эффективно. Я бы сказал, что влияние производительности незначительно для небольших массивов, но вы можете пойти с Set для более крупных.

Ответ 4

Вы можете преобразовать item1 в массив и присоединиться к ним:

my_array | [item1]

Ответ 5

Важно помнить, что класс Set и | метод (также называемый "Set Union" ) даст массив уникальных элементов, что отлично, если вы не хотите дубликатов, но который будет неприятным сюрпризом, если у вас есть неповторимые элементы в исходном массиве по дизайну.

Если у вас есть хотя бы один дублирующий элемент в исходном массиве, который вы не хотите потерять, повторение через массив с ранним возвратом - это наихудший вариант O (n), который не так уж плох в великом схема вещей.

class Array
  def add_if_unique element
    return self if include? element
    push element
  end
end

Ответ 6

Я не уверен, что это идеальное решение, но работал у меня:

    host_group = Array.new if not host_group.kind_of?(Array)
    host_group.push(host)