0

I have an app that needs to play several videos when prompted, but I would like the videos to be random and not repeat.

My current plan is to make an NSMutableDictionary where the key is the number for the video, and the value is just a basic string to tell me if it has been played or not. Then, when the video is to be played, I would randomly choose one and see if it has been played. Like so:

int randomNumber;
randomNumber = (arc4random() % 150) + 1;
if ([[videoDictionary valueForKey:[NSString stringWithFormat:@"%d", randomNumber]] isEqual:@"Played"])
{
   // This video has been played before. Make another random number and try again
} else {
   // This video has not been played before. Set the dictionary value to 'Played' and play the video
}

Is there a better way to do this? With over 100 videos this could start to get a bit daft when 90% of them have already been played.

Alan Taylor
  • 493
  • 4
  • 16
  • Anoop Vaidya's answer is probably what you're looking for. I personally would have an array of the videos, shuffle it, and then just loop straight through the array (shuffling again when you get to the end). Just my two cents. – jonhopkins Mar 18 '13 at 12:21
  • @jonhopkins: Even your answer is good :) – Anoop Vaidya Mar 18 '13 at 12:30

3 Answers3

4

Create a copy of your dictionary to NSMutableDictionary.

Chose by arc4random, play it.

Remove it from the dictionary.

NSInteger randomNumber=arc4random();
NSMutableDictionary *playingVideo=[NSMutableDictionary dictionaryWithDictionary:videoDictionary];
//select a video from playingVideo
NSString *key= [NSString stringWithFormat:@"%d", randomNumber];
// ....
//remove from there
[playingVideo removeObjectForKey:key]; 

EDIT 1:

As this is generating random number and searching in the dictionary. It may not be there or already replaced and even in 1000s iterations a particular number is not generated.

So in this case you can do as :

NSMutableDictionary *playingVideo=[NSMutableDictionary dictionaryWithDictionary:videoDictionary];
while(playingVideo.count){
    NSMutableArray *keys=[playingVideo allKeys];
    NSInteger randomNumber=arc4random()%keys.count;
    NSString *key=[NSString stringWithFormat:@"%d", keys[key]];
    NSString *videoToPlay=playingVideo[key];
    //play it
    [playingVideo removeObjectForKey:key];
} 
Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
  • Thank you Anoop, but I am a little confused by this. If the random number again generates a number that has been played before, and doesn't find anything in the dictionary for that, would I not be in the same situation that I am in with my own solution? – Alan Taylor Mar 18 '13 at 13:32
  • @AlanTaylor: check if `playingVideo[key]` is nil, if yes continue to next randomNumber generation. Or you can go for Undeph answer. – Anoop Vaidya Mar 18 '13 at 13:35
  • Thanks, I will give your answer a try when I get home and see if it will work for what I am looking to do. – Alan Taylor Mar 18 '13 at 13:59
  • I appreciate your update Anoop, but I'm not sure I understand what is happening here. How is making an array helping? And does this approach have an advantage over Undeph's answer? – Alan Taylor Mar 18 '13 at 16:35
  • The 2nd way is bit similar to undeph's solution. And it is better than my first answer, as i edited there with reason. I already said Undph answer has advantage over me, but i dont know why people give upvotes only by seeing points, I hate biased voting. – Anoop Vaidya Mar 18 '13 at 16:38
  • Thanks for the clarification! I'm going to try both tonight to see what works better for me. – Alan Taylor Mar 18 '13 at 16:50
  • I chose an array in the end, as it seemed to be the best thing for my needs. I appreciate this answer though, as if I already had a dictionary of videos this would have worked with my existing information which I'm sure would be valuable. Thank you again Anoop! – Alan Taylor Mar 19 '13 at 12:04
  • @AlanTaylor: I only asked you to go with his answer, his answer is better then me :) – Anoop Vaidya Mar 19 '13 at 12:23
3
  • Create a mutable array with all the numbers.
  • Shuffle the elements (What's the Best Way to Shuffle an NSMutableArray?)
  • Take the first element in the array and play the video
  • Remove the first element in the array
  • When the array is empty recreate it and shuffle again

With this approach you will not get the same "daftiness" at 90%.

Community
  • 1
  • 1
Mattias
  • 2,266
  • 2
  • 15
  • 16
1

When you are using the Random number you should make sure you use the random number from low to high limits.

(arc4random() % 10) + 1; // it will produce random number from 1 to 10
nsgulliver
  • 12,655
  • 23
  • 43
  • 64
  • Thanks! I would actually, do that, I got distracted while typing my question because I'm at work and didn't notice I'd not finished the line! – Alan Taylor Mar 18 '13 at 13:27