【募集】簡単そうでむずい... 綺麗に書ける人いないかな?(笑
はじめに
サービスの関係上、配列の中身の一部を固定するということが必要になったので、簡単にその方法を書いた。力技感満載できっと他にも良い方法はいくらでもあるけど、まぁとりあえずこれで良いかなと。
下記の仕様は、itemsという配列の中身を、指定したインデックス番号だけ固定し、ホワイトリスト式に他の場所だけシャッフルするというものです。
(今回の例は、アイテム2と4を固定し他をシャッフルします)
プログラム
# 数字かどうかのチェック
def is_numeric(value)
return true if value.is_a?(Numeric)
!!(Integer(value) rescue Float(value)) rescue false
end
# flexible_shuffle(引数1, 引数2)
# 引数1:Array(item1, item2, item3...)
# 引数2:Array([1,2,3...]), Integer(2), String("2", "1,2,3...")
def flexible_shuffle(items, holds)
shuffled_items = Array.new
checked_holds = Array.new
# 1: 引数チェック
if holds.class == Fixnum
checked_holds.push(holds)
elsif holds.class == String && is_numeric(holds)
checked_holds.push(holds.to_i)
elsif holds.class == Array
checked_holds = holds
else
return items
end
# 2: Index番号が指定されてない時だけ格納
items.each_with_index do |item, i|
shuffled_items.push(item) unless checked_holds.include?(i)
end
# 3: 1をシャッフル
shuffled_items.shuffle!
# 4: 2にIndex番号が指定されているものを挿入し戻す
checked_holds.each do |i|
shuffled_items.insert(i, items[i])
end
shuffled_items
end
# holdsの中身のインデックス番号は固定する(今回の例は、アイテム2と4を固定)
items = ["アイテム1", "アイテム2", "アイテム3", "アイテム4", "アイテム5"]
holds = "1,3"
出力結果例(10回試した結果)
["アイテム5", "アイテム2", "アイテム1", "アイテム4", "アイテム3"]
["アイテム3", "アイテム2", "アイテム5", "アイテム4", "アイテム1"]
["アイテム1", "アイテム2", "アイテム5", "アイテム4", "アイテム3"]
["アイテム5", "アイテム2", "アイテム3", "アイテム4", "アイテム1"]
["アイテム5", "アイテム2", "アイテム1", "アイテム4", "アイテム3"]
["アイテム5", "アイテム2", "アイテム3", "アイテム4", "アイテム1"]
["アイテム1", "アイテム2", "アイテム5", "アイテム4", "アイテム3"]
["アイテム5", "アイテム2", "アイテム1", "アイテム4", "アイテム3"]
["アイテム5", "アイテム2", "アイテム3", "アイテム4", "アイテム1"]
["アイテム5", "アイテム2", "アイテム1", "アイテム4", "アイテム3"]
確かにIndex番号1, 3のアイテム2とアイテム4だけ固定されて他がシャッフルされた。とりあえず良いかな。