Is there any easy method to randomise an array

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
songdg
Posts: 568
Joined: 04 Oct 2017, 20:04

Is there any easy method to randomise an array

02 Aug 2020, 21:25

I want to made that Array := [Item1, Item2, ..., ItemN] randomised.
User avatar
Chunjee
Posts: 1422
Joined: 18 Apr 2014, 19:05
Contact:

Re: Is there any easy method to randomise an array

02 Aug 2020, 21:33

.shuffle doesn't get much easier. https://biga-ahk.github.io/biga.ahk/#/?id=shuffle

Code: Select all

A.shuffle([1, 2, 3, 4])
; => [4, 1, 3, 2]

A.shuffle(["barney", "fred", "pebbles"])
; => ["pebbles", "barney", "fred"]
User avatar
boiler
Posts: 16955
Joined: 21 Dec 2014, 02:44

Re: Is there any easy method to randomise an array

02 Aug 2020, 22:08

Using native AHK (use v1.1.29 or later):

Code: Select all

Arr := RandomizeArray(["Howard", "Robin", "Fred", "Gary", "Ronnie"])

; display contents of Arr:
for i, v in Arr
	out .= v . A_Space
MsgBox, % out
return

RandomizeArray(arr) {
	newArr := []
	loop {
		Random, rand, 1, arr.Count()
		newArr.Push(arr.RemoveAt(rand))
	} until !arr.Count()
	return newArr
}
Caveat: This works if the items to be shuffled are strings or numbers, but not with an array of objects. To make it work with objects as well would be significantly slower, so there's a trade-off.
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: Is there any easy method to randomise an array

04 Aug 2020, 17:59

Inspired by JEE_StrRept by jeeswg:

Code: Select all

array := RandomizeArray(["Howard", "Robin", "Fred", "Gary", "Ronnie"])

for i, v in array, out := ""
	out .= v . A_Space
MsgBox, % RTrim(out)
return

RandomizeArray(arr) {
	loop % count:=arr.Count(ranStr:="") {
		Random, rand, 1, % count
		ranStr .= "{" . rand . "}" . A_Space
	}
	return StrSplit(Format(RTrim(ranStr), arr*), A_Space)
}
cheers

A_AhkUser
my scripts
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there any easy method to randomise an array

04 Aug 2020, 19:33

Code: Select all

Arr := RandomizeArray(["Howard", "Robin", "Fred", "Gary", "Ronnie"])
for k, v in Arr
   str .= v . " "
MsgBox, % str

RandomizeArray(Arr) {
   static d := Chr(1)
   for k, v in Arr
      str .= (str = "" ? "" : d) . v
   Sort, str, D%d% Random
   Return StrSplit(str, d)
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Is there any easy method to randomise an array

05 Aug 2020, 04:30

Hello, very nice to see you back again @A_AhkUser :superhappy: .
A_AhkUser wrote:
04 Aug 2020, 17:59

Code: Select all

loop % count:=arr.Count(ranStr:="") {
This is unacceptable though :terms: :lol: . (count accepts exactly zero parameters)

Cheers.
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: Is there any easy method to randomise an array

05 Aug 2020, 18:35

@teadrinker
Your answer is, as always, great and - unlike mine - as closely as possible to the question :"Is there any easy method to randomise an array?": your function is maybe one of the most transparent way to achieve this. Nevertheless, I think it is preferable in this case to handle a list by its indexes rather than its values - on which you have a priori no control whatsoever - or, at least, less control (e.g. values can be huge strings).

@Helgef
Helgef wrote:
05 Aug 2020, 04:30
(..) back again (...)
Yes back again, me and my deplorable coding way to write... I proceeded from the assumption - more than questionable, actually :terms: - that if the script doesn't throw an exception and gives the expected output, it is "acceptable"... Besides, it seems I'm here once again guilty of an excess of enthusiasm (that perhaps one will excuse me as one of its motive is here a symbolic debt): actually, my function does randomize but allows duplicates.

@Boiler Your function is fine but I would like to underline one point: unlike Chunjee's and teadrinker's one, your function modifies the user input - compare:

Code: Select all

myArr := ["Howard", "Robin", "Fred", "Gary", "Ronnie"]
ranArr := RandomizeArray(myArr)

for k, v in myArr, out := ""
	out .= v . A_Space
MsgBox, % RTrim(out)
for k, v in ranArr, out := ""
	out .= v . A_Space
MsgBox, % RTrim(out)
return

RandomizeArray(arr) {
	local
	clone := arr.clone(), count := clone.count()
	, (newArr:=[]).setCapacity(count), index := 0
	Loop {
		Random, rand, 1, % count
		newArr[++index] := clone.removeAt(rand)
	} until !(--count)
return newArr
}
Thanks for reading


@Helgef


A_AhkUser
my scripts
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: Is there any easy method to randomise an array

05 Aug 2020, 19:42

A_AhkUser wrote: it is preferable in this case to handle a list by its indexes rather than its values
Of course, the same principle can be applied to indexes as well:

Code: Select all

RandomizeArray(Arr) {
   NewArr := []
   Loop % Arr.Count()
      str .= (str ? "|" : "") . A_Index
   Sort, str, D| Random
   Loop, parse, str, |
      NewArr.Push( Arr[A_LoopField] )
   Return NewArr
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Dewi Morgan, doanmvu, Google [Bot], RSable and 388 guests