A、P、B、Nの4つの文字があるとしましょう。次のようにそれらを比較できるようにしたいです。
A > P > B > N > A
これはRubyでどのように達成されるでしょうか?
あなたのコメントから、これらの要素を順番に並べようとしているのではなく、それらのいくつかの間のバイナリ関係を定義しようとしているようです。後でそのリレーションをどのように使用するかによって、Ruby ではさまざまな方法でこれを行うことができます。
最も簡単な方法は、関連する要素の順序付けられたペアを定義することです:
MAP = [
['A', 'P'],
['P', 'B'],
['B', 'N'],
['N', 'A']
]
そして、2 つの要素を「比較」する必要があるときはいつでも使用します。
def beats? one, other
MAP.member?([one, other])
end
beats? 'A', 'B'
# => false
beats? 'A', 'P'
# => true
beats? 'N', 'A'
# => true
PS。次のようなものを使用して、文字列からマップを生成できます
MAP = 'APBNA'.chars.each_cons(2).to_a
考えられる解決策の1つは、たとえば、character
などを使用してクラスを作成するweight
ことです。そして<=>
、その中に演算子(メソッド)を実装します。
Comparable
このクラスにミックスインを含めることを忘れないでください。
class ComparableCharacter
include Comparable
attr_accessor :character, :weight
def <=>(another)
weight <=> another.weight
end
end
誰かが興味を持ってくれるなら、これは私の提案です(三項比較-比較は二項演算ではないので!!!):
class RockPaperScissors
ITEMS = %W(A P B N)
def self.compare(item, other_item)
new(item).compare other_item
end
def initialize(item)
# input validations?
@item = item
end
def compare(other_item)
# input validations?
indexes_subtraction = ITEMS.index(@item) - ITEMS.index(other_item)
case indexes_subtraction
when 1, -1
- indexes_subtraction
else
indexes_subtraction <=> 0
end
end
end
require 'test/unit'
include MiniTest::Assertions
assert_equal RockPaperScissors.compare('A', 'A'), 0
assert_equal RockPaperScissors.compare('P', 'P'), 0
assert_equal RockPaperScissors.compare('B', 'B'), 0
assert_equal RockPaperScissors.compare('N', 'N'), 0
assert_equal RockPaperScissors.compare('A', 'P'), 1
assert_equal RockPaperScissors.compare('P', 'A'), -1
assert_equal RockPaperScissors.compare('P', 'B'), 1
assert_equal RockPaperScissors.compare('B', 'P'), -1
assert_equal RockPaperScissors.compare('B', 'N'), 1
assert_equal RockPaperScissors.compare('N', 'B'), -1
assert_equal RockPaperScissors.compare('N', 'A'), 1
assert_equal RockPaperScissors.compare('A', 'N'), -1
平等:(A、A)比較
過半数:(A、P)
-
次の関数を使用できます。- (-1) -> 1
マイノリティ:(P、A)
-
次の関数を使用できます。- (1) -> -1
エッジケース1:(N、A)
<=>
次の関数を使用できます。(3 <=> 0) -> 1
エッジケース2:(A、N)
<=>
次の関数を使用できます。(3 <=> 0) -> 1
残りはリファクタリングです:関数で0
変換できます。0
<=>
a = "APBN"
h = {};(0...a.size).each{|i| h[a[i].chr] = i}
b = ['A','P','A','N', 'B','P']
b.sort_by{|t| h[t] }
もちろん、順序が悪いため、これはあなたの例では機能しません.A> P> Aになることはありませんが、少なくとも、必要な順序に従ってソートする方法を示しています.