25

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
4

9 に答える 9

21

多分これはあなたにとってより良く見えるでしょう:

a.insert(0, a.delete('c'))
于 2012-10-03T22:25:25.270 に答える
18

多分Array#rotateがあなたのために働くでしょう:

['a', 'b', 'c'].rotate(-1)
#=> ["c", "a", "b"]
于 2012-10-03T18:03:03.080 に答える
11

これは見た目よりも難しい問題です。次のテストを定義しました。

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

sort_by@Duopixel によって提案されたものはエレガントですが[3, 2, 1]、2 番目のテスト用に生成されます。

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

@tadman は を使用しますdeleteが、これは一致するすべての要素を削除するため、4 番目のテストの出力は[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_atnil を処理できないため、3 番目のテストに失敗しました。最後に、私は落ち着きました:

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

promote単純なアイデアが非常にトリッキーになる可能性があることを誰が知っていましたか?

于 2015-08-12T03:20:19.397 に答える
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"] 

これは、値の 1 つのインスタンスのみを再配置することに注意してください。配列に複数ある場合、後続の配列は最初の配列が削除されるまで移動されない可能性があります。

于 2012-10-03T18:14:31.390 に答える
4

最終的に、これが要素を前面に移動するための最も読みやすい代替手段であると考えました。

if @admin_users.include?(current_user)
  @admin_users.sort_by{|admin| admin == current_user ? 0 : 1}
end
于 2012-10-04T04:16:33.040 に答える
0

配列内のすべての要素が一意である場合、配列演算を使用できます。

> a = ['a', 'b', 'c']
=> ["a", "b", "c"]
> a -= "c"
=> ["a", "b"]
> a = ["c"] + a
=> ["c", "a", "b"]
于 2017-01-11T20:23:23.700 に答える