From: sin@... Date: 2020-03-07T06:39:17+00:00 Subject: [ruby-core:97392] [Ruby master Feature#16665] Add an Array#except_index method Issue #16665 has been updated by prajjwal (Prajjwal Singh). There needs to be more discussion on the behavior of this method. Logically, `except_indices` should be the complement of `values_at`, so for the purpose of writing test cases I added this stopgap: ```ruby def except_indices(*idx) self - self.values_at(*idx) end ``` And ended up with following test cases: ```ruby def test_except_indices a = @cls['a', 'b', 'c', 'd', 'e'] assert_equal(@cls['a', 'c'], a.except_indices(1, -2, -1)) assert_equal(@cls['c', 'd', 'e'], a.except_indices(0, 1, 10)) assert_equal(@cls['a', 'b', 'c', 'd', 'e'], a.except_indices(10, 20, 30)) assert_equal(@cls[], a.except_indices(0..4)) assert_equal(@cls['c', 'd', 'e'], a.except_indices(0..1)) assert_equal(@cls['c'], a.except_indices(0..1, 3..4)) assert_equal(@cls['a', 'b', 'c'], a.except_indices(3..15)) # Logically except_indices is the complement of values_at, and values_at # returns an empty array when given a range starting with a negative number. # This could change in the future. # https://bugs.ruby-lang.org/issues/16678 assert_equal(@cls['a', 'b', 'c', 'd', 'e'], a.except_indices(-1..2)) end ``` However, I'm left wondering whether that last case is something that should be fixed (with `values_at` being changed to accomodate ranges starting with a negative), or if this is fine. Any feedback welcome. Full commit is at - https://github.com/Prajjwal/ruby/commit/0bb2788fb249df4381982cea957c7feaadccd0ed. ---------------------------------------- Feature #16665: Add an Array#except_index method https://bugs.ruby-lang.org/issues/16665#change-84522 * Author: alex_golubenko (Alex Golubenko) * Status: Open * Priority: Normal ---------------------------------------- The main idea is to implement a method that we can use to exclude elements from the array by their indices. For example: ``` ruby %w( a b c d e f).except_index(0, -1) => ["b", "c", "d", "e"] %w( a b c d e f g h ).except_index(0..1, 3, -2..-1) => ["c", "e", "f"] ``` I was meeting many questions on the StackOverflow about how to do such functionality also found many topics about it. So I think it might a helpful addition. I spent a few days finding the proper solution on Ruby that might be acceptable with integers and ranges(both positive and negative) and has good performance: ```ruby def except_index(*indexes) indexes.each_with_object(dup) do |ind, obj| ind.is_a?(Range) ? ind.each { |i| obj[i] = false } : obj[ind] = false end.select(&:itself) end ``` As you can see it's have not the best readability so I think it's a good point to add a built-in method on C. -- https://bugs.ruby-lang.org/ Unsubscribe: