0

Is there anyway to shuffle Special Sets of Item in NSMutableArray?

for example this is my NSMutableArray :

self.resultsdict : (
        {
        Id = 261496;
        packID = 1057;
        title = "cat"
},
        {
        Id = 261497;
        packID = 1057;
        title = "dog"
 },
        {
        Id = 261498;
        packID = 1057;
        title = "fish"
},
        {
        Id = 261499;
        packID = 1059;
        title = "donkey"
},
        {
        Id = 261500;
        packID = 1060;
        title = "cow"
},

now i want to shuffle items with the "packID = 1057" in the list. there other item should be with

normal order.

output for title should be : [ cat , dog , fish ] <- in random order and the rest [ donkey , cow]

in normal order.

i can shuffle all list with this code , but is there any way to modify it for above propose ?

    for (int x = 0; x < [self.resultsdict count]; x++) {
        int randInt = (arc4random() % ([self.resultsdict count] - x)) + x;
        [self.resultsdict exchangeObjectAtIndex:x withObjectAtIndex:randInt];
    }

one solution that i find out is to make two NSMutableArray , one for shuffle and another one for

normal order and after shuffle i them merge with addObjectsFromArray.

but this solution is kinda hard for multiple shuffle list , like this :

self.resultsdict : (
        {
        Id = 261496;
        packID = 1057;
        title = "cat"
},
        {
        Id = 261497;
        packID = 1057;
        title = "dog"
 },
        {
        Id = 261498;
        packID = 1057;
        title = "fish"
},
        {
        Id = 261499;
        packID = 1059;
        title = "donkey"
},
        {
        Id = 261500;
        packID = 1060;
        title = "cow"
},
        {
        Id = 261501;
        packID = 1060;
        title = "AyeAye"
},

with following condition => "packID = 1057" and "packID = 1060"

and following output :

[ cat , dog , fish ] <- in random order + [ donkey ] + [ cow , aye aye ] <- in random order.

More info :

the program makes query for test with deferent PackID.

SELECT * FROM tests WHERE packID IN ("1057","1059","1060")

the result of query will be inserted into "self.resultsdict"

 FMResultSet *results_packs =  [db executeQuery:sql];
    while([results_packs next])
    {

        [self.resultsdict addObject:[results_packs resultDictionary]];
    }

user have a shuffle ability for test query. for example he/she can select to show shuffle version

of "1057","1060" and orderd version of "1059".

now what i want to do is modify my normal shuffle code to accept array of condition, like shuffle

item per following keys ("1057","1060").

thanks in forward

Ahad Porkar
  • 1,666
  • 2
  • 33
  • 68
  • It's a mater of algo and task and is hardly relative to iOS or Obj-C. Your task isn't concrete, what is there are more object with ID=1057 and they're located at the end of the list or just spread randomly, what should be the result? Should they be mixed just among "1057's" or should each group of such items be shuffled? – Gobra Dec 06 '14 at 08:24
  • your right , i will update my question asap. – Ahad Porkar Dec 06 '14 at 08:26

1 Answers1

1

Well, you can scan the array checking items within the ID range (this can also be achieved via NSPredicate) and build up a set of indices S that has all the positions of the array elements you're interested in.

Now, having S prepared, you can use the same exchanging trick you have in your sample, but instead of pure random - use a limited one, i.e. exchange objects indexed in S with some other objects indexed in S.

The pseudocode would be something like that:

foreach (index in S)
{
  otherIndex = S.randomIndex()
  array.swapObjects(index, otherIndex)
}

If I got your task properly, this code will do the job: it will randomly shuffle objects of some specific kind, leaving all the rest as is.

UPD: In order to build the S set you must catch the moment user changes his selection and run a method of your own that will either:

  • Scan the array manually checking for the records ID value and constructing a NSMutableSet
  • Run NSPredicate on array, scanning for the IDs you need

Predicate seems to be more SQL-like way here and would like approximately like that:

NSPredicate* scanRecordWithIDsPredicate = [NSPredicate predicateWithFormat:@"packID IN %@", userSpecifiedSetOfIDs];
NSSet* setOfIndicies = [array filteredArrayUsingPredicate: scanRecordWithIDsPredicate];

UPD2: Since you already have a SQL-backhroud, I guess you can use something like that as well: MySQL: Shuffle a limited query result? , shuffling the output right in the query.

Community
  • 1
  • 1
Gobra
  • 4,263
  • 2
  • 15
  • 20
  • thanks for answer , this is exactly what i want to do. But there is one thing.how can i make Sets of S Indices? since the array condition is dynamic. – Ahad Porkar Dec 06 '14 at 12:35