296

Вопрос по ruby – Как я могу удалить один элемент из массива по значению

У меня есть массив элементов в Ruby

[2,4,6,3,8]

Мне нужно удалить элементы со значением3 например

Как я могу это сделать?

  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded.deleteError: User Rate Limit Exceeded-. .deleteError: User Rate Limit Exceeded-Error: User Rate Limit Exceeded[ 1, 2, 3 ] - [ 2 ]Error: User Rate Limit Exceeded[ 1, 3 ]Error: User Rate Limit Exceeded[ 1, 2, 3 ].delete( 2 )Error: User Rate Limit Exceeded2.

    от
  • Error: User Rate Limit Exceeded[1,2,3] - [2]Error: User Rate Limit Exceeded[1,2,3].delete(2)Error: User Rate Limit ExceededdeleteError: User Rate Limit Exceededmodifies the original arrayError: User Rate Limit Exceeded[1,2,3] - [3]Error: User Rate Limit Exceedednew array.

    от
  • array - subArrayError: User Rate Limit ExceededArray of ArraysError: User Rate Limit Exceededarray.delete(subArray)Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Чтобы объявить в IRB, вам нужно добавить метод в массивclass Array; def except(*values); self - values; end; end.

    от
  • Ваше решение не работает наirb приставка2.2.1 :007 > [1, 2, 3, 4].except(3, 4) NoMethodError: undefined method except for [1, 2, 3, 4]:Array from (irb):7 from /usr/share/rvm/rubies/ruby-2.2.1/bin/irb:11:in <main>

    от
  • @ Зак конечно, но этот ответ уже упоминался (как и очень краткий-= путьa-=[4] то естьa=a-[4] . [3,4]-[4]что я сказал, что мне понравилось), но я хотел бы упомянуть еще один возможный способ.

    от
  • Этот метод также имеет преимущество, заключающееся в возврате массива вместо удаленного элемента.

    от
  • Но вы не можете просто использовать.delete(6)

    от
  • Вы не нуждаетесь вvalue.kind_of(Array) тестовое задание. Просто используйтеself - Array(value).

    от
  • Что если есть несколько записей по 3, и мы хотим удалить только одну из них? (это связано, так что лучше всего спросить здесь)

    от
  • Другим следствием, которое следует учитывать, является то, чтоdelete мутирует базовый массив, тогда как- создает новый массив (который вам возвращается) без удаленного значения. В зависимости от вашего варианта использования любой подход может иметь смысл.

    от
  • Мне лично нравится[1, 2, 3, 4, 5] - [3] что приводит к=> [1, 2, 4, 5] отirb.

    от
  • интересно, почемуdelete array.delete(3) не работает внутри ruby на рельсах контроллера

    от ImranNaqvi
  • может быть связано сactive record методdelete

    от ImranNaqvi
14 ответов
  • 7

    Я улучшил решение Niels

    class Array          
      def except(*values)
        self - values
      end    
    end
    

    Теперь вы можете использовать

    [1, 2, 3, 4].except(3, 4) # return [1, 2]
    [1, 2, 3, 4].except(4)    # return [1, 2, 3]
    

  • 2

    Поэтому

    когда у вас есть несколько вхождений 3, и вы хотите удалить только первое вхождение 3, вы можете просто сделать что-то, как показано ниже.

    arr = [2, 4, 6, 3, 8, 10, 3, 12]
    
    arr.delete_at arr.index 3
    
    #This will modify arr as [2, 4, 6, 8, 10, 3, 12] where first occurrence of 3 is deleted. Returns the element deleted. In this case => 3.
    

  • 1

    Если вы также хотите сделать эту операцию удаления цепочкой

    чтобы можно было удалить какой-либо элемент и продолжить операции цепочки в результирующем массиве, используйтеtap:

    [2, 4, 6, 3, 8].tap { |ary| ary.delete(3) }.count #=> 4
    

  • 417

    Я думаю, что я понял это: a = [2,4,6,3,8] a.delete(3)

    Я думаю, что я понял это:

    a = [2,4,6,3,8]
    a.delete(3)
    

  • 19

    .delete_at(3) 3 здесь быть позиции.

  • 3

    Вы также можете обезьяна исправить это. Я никогда не понимал

    почему у Руби естьexcept метод дляHash но не дляArray:

    class Array
      def except value
        value = value.kind_of(Array) ? value : [value]
        self - value
      end
    end
    

    Теперь вы можете сделать:

    [1,3,7,"436",354,nil].except(354) #=> [1,3,7,"436",nil]
    

    Или же:

    [1,3,7,"436",354,nil].except([354, 1]) #=> [3,7,"436",nil]
    

  • 18

    Вы можете просто запустить: [2,4,6,3,8].delete(3)

    Вы можете просто запустить:

    [2,4,6,3,8].delete(3)
    

  • 24

    мне нравится

    -=[4] Способ, упомянутый в других ответах для удаления элементов, значение которых равно 4.

    Но есть такой способ:

    irb(main):419:0> [2,4,6,3,8,6].delete_if{|i|i==6}
    => [2, 4, 3, 8]
    irb(main):420:0>
    

    упоминается где-то в & quot;Основные операции с массивами& quot ;, после упоминанияmap функция.

  • 33

    Я не уверен

    что кто-то это сказал, но Array.delete () и - =value удалит каждый экземпляр значения, переданного ему в массиве. Чтобы удалить первый экземпляр определенного элемента, вы можете сделать что-то вроде

    arr = [1,3,2,44,5]
    arr.delete_at(arr.index(44))
    
    #=> [1,3,2,5]
    

    Там может быть более простой способ. Я не говорю, что это лучшая практика, но это то, что следует признать.

  • 0

    Неразрушающее удаление первого появления:

    a = [2, 4, 6, 3, 8]
    n = a.index 3
    a.take(n)+a.drop(n+1)
    

  • 12

    Вот несколько тестов:

    require 'fruity'
    
    
    class Array          
      def rodrigo_except(*values)
        self - values
      end    
    
      def niels_except value
        value = value.kind_of?(Array) ? value : [value]
        self - value
      end
    end
    
    ARY = [2,4,6,3,8]
    
    compare do
      soziev  { a = ARY.dup; a.delete(3);               a }
      steve   { a = ARY.dup; a -= [3];                  a }
      barlop  { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
      rodrigo { a = ARY.dup; a.rodrigo_except(3);         }
      niels   { a = ARY.dup; a.niels_except(3);           }
    end
    
    # >> Running each test 4096 times. Test will take about 2 seconds.
    # >> soziev is similar to barlop
    # >> barlop is faster than steve by 2x ± 1.0
    # >> steve is faster than rodrigo by 4x ± 1.0
    # >> rodrigo is similar to niels
    

    И снова с большим массивом, содержащим много дубликатов:

    class Array          
      def rodrigo_except(*values)
        self - values
      end    
    
      def niels_except value
        value = value.kind_of?(Array) ? value : [value]
        self - value
      end
    end
    
    ARY = [2,4,6,3,8] * 1000
    
    compare do
      soziev  { a = ARY.dup; a.delete(3);               a }
      steve   { a = ARY.dup; a -= [3];                  a }
      barlop  { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
      rodrigo { a = ARY.dup; a.rodrigo_except(3);         }
      niels   { a = ARY.dup; a.niels_except(3);           }
    end
    
    # >> Running each test 16 times. Test will take about 1 second.
    # >> steve is faster than soziev by 30.000000000000004% ± 10.0%
    # >> soziev is faster than barlop by 50.0% ± 10.0%
    # >> barlop is faster than rodrigo by 3x ± 0.1
    # >> rodrigo is similar to niels
    

    И еще больше с большим количеством дубликатов:

    class Array          
      def rodrigo_except(*values)
        self - values
      end    
    
      def niels_except value
        value = value.kind_of?(Array) ? value : [value]
        self - value
      end
    end
    
    ARY = [2,4,6,3,8] * 100_000
    
    compare do
      soziev  { a = ARY.dup; a.delete(3);               a }
      steve   { a = ARY.dup; a -= [3];                  a }
      barlop  { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
      rodrigo { a = ARY.dup; a.rodrigo_except(3);         }
      niels   { a = ARY.dup; a.niels_except(3);           }
    end
    
    # >> Running each test once. Test will take about 6 seconds.
    # >> steve is similar to soziev
    # >> soziev is faster than barlop by 2x ± 0.1
    # >> barlop is faster than niels by 3x ± 1.0
    # >> niels is similar to rodrigo
    

  • 20

    Предполагая

    что вы хотите удалить 3 по значению в нескольких местах в массиве, Я думаю, что Ruby способ сделать эту задачу будет использовать метод delete_if:

    [2,4,6,3,8,3].delete_if {|x| x == 3 } 
    

    Вы также можете использовать delete_if для удаления элементов в сценарии «массив массивов».

    Надеюсь, что это решит ваш запрос

  • 60

    Другой вариант: a = [2,4,6,3,8] a -= [3]

    Другой вариант:

    a = [2,4,6,3,8]
    
    a -= [3]
    

    что приводит к

    => [2, 4, 6, 8] 
    

  • 192

    Заимствование из

    Travis в комментариях это лучший ответ:

    I personally like [1, 2, 7, 4, 5] - [7] which results in => [1, 2, 4, 5] from irb

    I modified his answer seeing that 3 was the third element in his example array. This could lead to some confusion for those who don't realize that 3 is in position 2 in the array.