从具有多个匹配对象的数组中删除一个对象

时间:2015-06-01 19:46:47

标签: arrays ruby

我有一个数组:

array = ['a', 'b', 'c', 'a', 'b', 'a', 'a']

排序,只是为了更容易查看:

array = ['a', 'a', 'a', 'a', 'b', 'b', 'c']

我想删除,例如,a中的三个。 array.delete('a')删除每a new_array = array.sort.join.sub!('aaa', '').split(//)

以下代码'有效'但我认为你会认为这绝对是可怕的。

array

我如何更干净地做到这一点?

为了提供更多关于我在这里做什么的信息,我将一些字符串异步推入数组。这些字符串可以(通常是)彼此相同。如果有一定数量的匹配字符串,则触发一个动作,匹配的对象被删除(就像俄罗斯方块,我猜),然后过程继续。

在运行以下代码之前,['a', 'a', 'a', 'b']可以是while array.count(product[:name]) >= product[:quantity] # trigger an event product[:quantity].times do array.slice!(array.index(product[:name])) end end

product[:name]

假设aproduct[:quantity]3['b'],则在上述代码运行后,数组应为<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:custom="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="0dp" android:paddingRight="0dp" android:paddingTop="0dp" android:paddingBottom="0dp" android:background="@mipmap/splashscreen_drawable" tools:context="quasiaffatto.myapplication.SplashScreen"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_logo" android:textColor="@color/color_white" android:text="App title" android:textSize="50sp" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:textStyle="bold" android:gravity="center"/> </RelativeLayout>

3 个答案:

答案 0 :(得分:2)

slice可能是您正在寻找的东西:

3.times {array.slice!(array.index('a'))}

答案 1 :(得分:2)

如果要维护或转换数组,使其只有每个元素的一个实例,则可以使用uniq或Set而不是数组。

array = ['a', 'b', 'c', 'a', 'b', 'a', 'a']
array.uniq # => ["a", "b", "c"]

require 'set'
array.to_set # => #<Set: {"a", "b", "c"}>

Set会自动为您保留所有元素的唯一性,如果您有大量可能重复的元素并且不想在内存中累积它们,这将非常有用他们是uniq

@sawa提到这看起来像是&#34; XY problem&#34;,我同意。

问题的根源是使用数组而不是哈希作为基本容器。当你有一个队列或事物列表来按顺序处理 时,一个数组很好,但是当你需要跟踪事物的数量时它很可怕,因为你必须走这个数组找出你有多少东西。当您将数组作为源时,有一些方法可以强制从数组中获取所需的信息。

因为看起来他确定了真正的问题,所以这里有一些构建块用于解决问题。

如果你有一个数组,想要弄清楚有多少不同的元素,以及它们的数量:

array = ['a', 'a', 'a', 'a', 'b', 'b', 'c', 'c']
array_count = array.group_by { |i| i }.map{ |k, v| [k, v.size] }.to_h
# => {"a"=>4, "b"=>2, "c"=>2}

从那时起,很容易找出哪些超过一定数量:

array_count.select{ |k, v| v >= 3 } # => {"a"=>4}

为了快速从阵列中删除某些内容的元素,处理后您可以使用一组&#34; difference&#34;操作:

array = ['a', 'a', 'a', 'a', 'b', 'b', 'c']
array -= ['a']
# => ["b", "b", "c", "c"]

delete_if

array.delete_if { |i| i == 'a' }
array # => ["b", "b", "c"]

答案 2 :(得分:2)

我认为你有一个XY问题。您应该使用具有出现次数的哈希作为值而不是数组。

hash = Hash.new(0)

如果要添加实体,则应执行以下操作:

hash["a"] += 1

如果要将数字限制为某个值,例如k,请执行:

hash["a"] += 1 unless hash["a"] == k