0

I have a function that selects a random object form an array. I have wrapped the internal bash function RANDOM, and implemented my function like that:

function rand() { echo $[ $RANDOM % $2 + $1 ]; }
function rand_obj() { objs=($@); index=$(rand 0 $#); echo ${objs[$index]} ; }

It works just fine, but I would love to learn a way of implementing it without the intermediate array objs. Any ideas? Thanks in advance

2
  • shift $(( $(rand 1 $#) - 1 )); echo "$1"? Commented Jun 21, 2015 at 14:19
  • @EtanReisner, why do't you put it as an answer? Commented Jun 21, 2015 at 14:24

2 Answers 2

2

Does something like this

rand_obj() {
    shift $(( $(rand 1 $#) - 1 )); echo "$1"
}

do what you want?

The above has problems with arguments that end with newlines.

Command Substitution always removes trailing newlines.

To handle that scenario you'd need to stick a dummy character/etc. at the end and remove it at use time. Something like this:

rand_obj() {
    shift $(( $(rand 1 $#) - 1 )); echo "$1x"
}
elem=$(rand_obj ... ... ... ... ...)
elem=${elem%x}
Sign up to request clarification or add additional context in comments.

Comments

2

there are too many ways. here is almost oneliner, but assume you have no space in your strings, and you never touched IFS:

echo ${ARRAY[@]} | tr ' ' '\n' | shuf -n1

2 Comments

Thanks, very nice - I've never encountered shuf. But i am looking for something that does not involve too many calls
To take care of spaces, & assuming that there are no newlines in arguments, change echo ${ARRAY[@]} | tr ' ' '\n' to printf "%s\n" "${ARRAY[@]}"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.