是否有只删除1个匹配数组元素的方法



例如a = [1,2,3,1]

如果使用a.delete 1,则结果为a = [2,3]

有没有一种方法可以在有限制的情况下从数组中删除?伪代码:

a = [1,2,3,4,1]
a.delete(1, *limit 1*) 
#=> [2,3,4,1]

我能想到一个想法,那就是-

n.times { array.delete_at array.index(item) }

delete_at-删除指定索引处的元素,返回该元素;如果索引超出范围,则返回nil

index-返回ary中第一个对象的索引,使对象==到obj。

您可以将逻辑封装在方法中,如下所示:-

def delete_with_limit(array, item, limit)
  count = array.count(item)
  raise "only #{count} is present, and you are expecting #{limit}" if limit > count
  limit.times { array.delete_at array.index(item) }
  array
end
array = [1,2,1,1,3,5]
delete_with_limit(array, 1, 2) # => [2, 1, 3, 5]
array = [1,2,1,1,3,5]
delete_with_limit(array, 1, 4)
#  `delete_with_limit': only 3 is present, and you are expecting 4 (RuntimeError)

一个有效的解决方案:

n = 1
a = [1,2,3,4,1]
a.delete_at(a.index(n) || a.length)
#=> [2,3,4,1]

这是另一种方法。感谢@Uri提出的改进建议。(如果你对我最初的内容感兴趣,请查看编辑历史。(

方法

def delete_some(arr, target, nbr_to_delete)
  arr.select { |e| e==target ?
                (nbr_to_delete > 0 ? (nbr_to_delete -= 1; false) : true) :
                true }
end

示例

a = [1,2,3,1,2,1,1,3]
delete_some(a,1,0) #=> [1, 2, 3, 1, 2, 1, 1, 3]
delete_some(a,1,1) #=> [2, 3, 1, 2, 1, 1, 3]
delete_some(a,1,2) #=> [2, 3, 2, 1, 1, 3]
delete_some(a,1,3) #=> [2, 3, 2, 1, 3]
delete_some(a,1,4) #=> [2, 3, 2, 3]
delete_some(a,1,5) #=> [2, 3, 2, 3]

只删除一个:

if idx = a.index(n)
  a.delete_at(idx)
end

对于通用limit > 0

def delete_first(arr, item, limit = 1)
  arr.reject! { |i| i == item && (limit -= 1) >= 0 } 
end

具有额外的优化(如果已经丢弃了所有相关元素,则不会通过所有阵列(:

def delete_first(arr, item, limit = 1)
  arr.reject! { |i| return arr if limit == 0; i == item && limit -= 1 }
end

最新更新