AppleScript でリストをシャッフルする簡単な方法はありますか?
私はいくつかの検索を行い、空白を描きました。
Fisher-Yates アルゴリズムの短いバージョン:
on shuffle(l)
set i to count of l
repeat while i ≥ 2
set j to random number from 1 to i
tell l to set {item i, item j} to {item j, item i}
set i to i - 1
end repeat
l
end shuffle
set l to {}
repeat 1000 times
set end of l to random number from 1 to 1000
end repeat
shuffle(l)
i * ... * 2 = i! があります。乱数の可能なシーケンス。それらはすべて i! リストの順列。
スクリプト オブジェクトを使用する高速バージョン:
on shuffle(input)
script s
property l : input
end script
set i to count of l of s
repeat while i ≥ 2
set j to random number from 1 to i
set {item i of l of s, item j of l of s} to {item j of l of s, item i of l of s}
set i to i - 1
end repeat
l of s
end shuffle
スクリプトにかかった時間は次のとおりです。
したがって、最初のスクリプトは指数関数的な時間の複雑さを持っていました。regulus によって投稿されたスクリプトは、わずかに遅くなりました。
最初のスクリプトを scpt として保存し、リストに 10000 個の要素を追加したとき、コンパイル済みスクリプトに保存できる項目数の制限に達しました。
新しいリストのアイテムが一意である必要がない場合は、非常に効率的な
set selectedItemVar to some item of list someItemListVar
私はそれをクラックしたと思います。使いやすさを追求した機能を搭載。
set myList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
set answer to listShuffle(myList)
on listShuffle(theList)
set listLength to count of theList
repeat while listLength > 1
set r to random number from 1 to listLength
set item1 to item listLength of theList
set item2 to item r of theList
set item listLength of theList to item2
set item r of theList to item1
set listLength to listLength - 1
end repeat
return theList
end listShuffle