在Ruby中将元素重新定位到数组的前面

时间:2012-10-03 18:00:54

标签: ruby

即使来自javascript,这对我来说也很残酷:

irb
>> a = ['a', 'b', 'c']
=> ["a", "b", "c"]
>> a.unshift(a.delete('c'))
=> ["c", "a", "b"]

将元素放置在数组的前面是否更清晰?

编辑我的实际代码:

if @admin_users.include?(current_user)
  @admin_users.unshift(@admin_users.delete(current_user))
end

9 个答案:

答案 0 :(得分:16)

也许Array#rotate会对你有用:

['a', 'b', 'c'].rotate(-1)
#=> ["c", "a", "b"]

答案 1 :(得分:14)

也许这对你来说更好看:

a.insert(0, a.delete('c'))

答案 2 :(得分:6)

这比看起来更棘手。我定义了以下测试:

describe Array do
  describe '.promote' do
    subject(:array) { [1, 2, 3] }

    it { expect(array.promote(2)).to eq [2, 1, 3] }
    it { expect(array.promote(3)).to eq [3, 1, 2] }
    it { expect(array.promote(4)).to eq [1, 2, 3] }
    it { expect((array + array).promote(2)).to eq [2, 1, 3, 1, 2, 3] }
  end
end
@Duopixel提出的

sort_by很优雅,但第二次测试会产生[3, 2, 1]

class Array
  def promote(promoted_element)
    sort_by { |element| element == promoted_element ? 0 : 1 }
  end
end

@tadman使用delete,但这会删除所有匹配的元素,因此第四个测试的输出为[2, 1, 3, 1, 3]

class Array
  def promote(promoted_element)
    if (found = delete(promoted_element))
      unshift(found)
    end

    self
  end
end

我尝试使用:

class Array
  def promote(promoted_element)
    return self unless (found = delete_at(find_index(promoted_element)))
    unshift(found)
  end
end

但是第三次​​测试失败了,因为delete_at无法处理nil。最后,我决定:

class Array
  def promote(promoted_element)
    return self unless (found_index = find_index(promoted_element))
    unshift(delete_at(found_index))
  end
end

谁知道promote之类的简单想法可能会如此棘手?

答案 3 :(得分:5)

如果通过“优雅”表示即使以非标准为代价也更具可读性,您总是可以编写自己的方法来增强数组:

class Array
  def promote(value)
    if (found = delete(value))
      unshift(found)
    end

    self
  end
end

a = %w[ a b c ]
a.promote('c')
# => ["c", "a", "b"] 
a.promote('x')
# => ["c", "a", "b"] 

请记住,这只会重新定位值的单个实例。如果数组中有多个,则在删除第一个之前,可能不会移动后续的数据。

答案 4 :(得分:3)

最后,我认为这是将元素移到前面最可读的替代方法:

if @admin_users.include?(current_user)
  @admin_users.sort_by{|admin| admin == current_user ? 0 : 1}
end

答案 5 :(得分:2)

加我的两分钱:


User.findById({_id:jwt_payload._doc._id},callback);

优点:

  • 可以将多个项目移动到数组前面

缺点:

  • 这将删除所有重复项,除非它是所需的结果。

示例 - 将所有 奇数 数字移到前面(并使数组唯一):

array.select{ |item| <condition> } | array

结果:

data = [1, 2, 3, 4, 3, 5, 1]
data.select{ |item| item.odd? } | data
# Short version:
data.select(&:odd?) | data

答案 6 :(得分:1)

另一种方式:

a = [1, 2, 3, 4]
b = 3

[b] + (a - [b])
=> [3, 1, 2, 4]

答案 7 :(得分:0)

如果数组中的所有元素都是唯一的,则可以使用数组运算:

> a = ['a', 'b', 'c']
=> ["a", "b", "c"]
> a -= "c"
=> ["a", "b"]
> a = ["c"] + a
=> ["c", "a", "b"]

答案 8 :(得分:0)

基于以上内容:

class Array
  def promote(*promoted)
    self - (tail = self - promoted) + tail
  end
end

[1,2,3,4].promote(5)
=> [1, 2, 3, 4]
[1,2,3,4].promote(4)
=> [4, 1, 2, 3]
[1,2,3,4].promote(2,4)
=> [2, 4, 1, 3]