0

に 2 つ作成NSMutableArrayviewDidLoad、 に追加しNSMutableDictionaryます。1つの配列でシャッフルしてみたら、大丈夫でした。しかし、問題は、2つの配列を個別にシャッフルするとうまくいかず、どういうわけかインデックスが混同されてしまうことです。

これが私の配列のコードです(最初の配列):

self.items1 = [NSMutableArray new];

for(int i = 0; i <= 100; i++) 
{ 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [paths objectAtIndex:0];

    NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"[Images%d.png", i]]; 
    if([[NSFileManager defaultManager] fileExistsAtPath:savedImagePath]){ 
        self.container = [[NSMutableDictionary alloc] init];
        [container setObject:[UIImage imageWithContentsOfFile:savedImagePath] forKey:@"items1"]; 
        [container setObject:[NSNumber numberWithInt:i] forKey:@"index1"];
        [items1 addObject:container];           
    } 
} 

NSLog(@"Count : %d", [items1 count]);  

[items1 enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
    NSLog(@"%@ images at index %d", object, index);
}];

(2 番目の配列):

self.items2 = [NSMutableArray new];  
for(int i = 0; i <= 100; i++) 
{ 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [paths objectAtIndex:0];

    NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"secondImages%d.png", i]]; 
    NSLog(@"savedImagePath=%@",savedImagePath);
    if([[NSFileManager defaultManager] fileExistsAtPath:savedImagePath]){ 
        self.container = [[NSMutableDictionary alloc] init];
        [container setObject:[UIImage imageWithContentsOfFile:savedImagePath] forKey:@"items2"]; 
        [container setObject:[NSNumber numberWithInt:i] forKey:@"index2"];
        [items2 addObject:container];
    } 
} 

NSLog(@"Count : %d", [items2 count]);  

[items2 enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
    NSLog(@"%@ images at index %d", object, index);
}];

iCarousel私の配列を使用している場所の私の見解:

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{

    if (carousel == carousel1)
    {
        NSDictionary *obj = [items1 objectAtIndex:index];
        view = [[UIImageView alloc] initWithImage:[obj objectForKey:@"items1"]];
        view.tag = index;
    }
    else
    {
        NSDictionary *obj = [items2 objectAtIndex:index];
        view = [[UIImageView alloc] initWithImage:[obj objectForKey:@"items2"]];
        view.tag = index;
    }

    return view;
}

次に、シャッフルコード(他の配列に複製しようとしましたが、機能しませんでした):

   srandom(time(NULL));
    NSUInteger count = [items1 count];
    for (NSUInteger i = 0; i < count; ++i) {
        int nElements = count - i;
        int n = (random() % nElements) + i;
        [items1 exchangeObjectAtIndex:i withObjectAtIndex:n];
    }

上記のコードを使用して (または他の提案がある場合)、2 つの配列を使用してシャッフルするにはどうすればよいですか? ありがとう

私のもう1つの問題は、シャッフルメソッドのクラスをサブクラス化しようとするか、上記のコードを使用してインデックスを混在させようとするときです。例えば:

オブジェクト: リンゴ、ボール、ニンジン、犬

インデックス: 1 2 3 4

しかし、シャッフルしたときの私の見解では:

オブジェクト: ニンジン, リンゴ, 犬, バレ

索引: 2 4 1 3

カルーセルが停止すると、表示中の画像が削除されるという方法もあります。

4

3 に答える 3

1

最もクリーンなソリューション: Objective-C カテゴリを使用する

NSMutableArray+RandomUtils.h

#import <Foundation/Foundation.h>


@interface NSMutableArray (RandomUtils) 
-(void)shuffle;
@end

NSMutableArray+RandomUtils.m

#import "NSMutableArray+RandomUtils.h"

@implementation NSMutableArray (RandomUtils)
-(void)shuffle
{
    NSUInteger count = [self count];
    for (NSUInteger i = 0; i < count; ++i) {
        NSUInteger nElements = count - i;
        NSUInteger n = (arc4random() % nElements) + i;
        [self exchangeObjectAtIndex:i withObjectAtIndex:n];
    }
}

@end

MSMutableArray をシャッフルする場所にインポートします

[array1 shuffle];
[array2 shuffle];

混合インデックスの問題を再現しようとしましたが、できません

NSMutableArray *sarray = [NSMutableArray arrayWithArray: @[@"carrots", @"apple", @"dog", @"balle"]];

NSLog(@"%@", sarray);
[sa enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"%@ object at index %lu", obj, idx);
}];

[sarray shuffle];
 NSLog(@"%@", sarray);
[sarray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"%@ object at index %lu", obj, idx);
}];

結果は

(
    carrots,
    apple,
    dog,
    balle
)
carrots object at index 0
apple object at index 1
dog object at index 2
balle object at index 3
 (
    balle,
    dog,
    carrots,
    apple
)
balle object at index 0
dog object at index 1
carrots object at index 2
apple object at index 3

ところで: あなたの例も正しくありません: 配列に 4 つのオブジェクトがある場合、インデックスは 0 から始まり、最大値は 3 です。1 と 4 があります。

そのため、配列はシャッフルされ、インデックスは問題ありません。あなたが示していない他の問題がコードにあるに違いありません。

実際のコードを放棄する必要があります。


私が理解しているとしても、あなたが何を望んでいるのか、私にはまだわかりません。しかし、あなたのコメントから、配列をシャッフルしたいが、古いインデックスを保持したいと思うでしょう。インデックスは配列内のオブジェクトの位置であるため、これは不可能です。ただし、いつでも元のインデックスをどこかに自由に保存できます。
または、配列をコピーして、そのうちの 1 つをシャッフルします。これで、両方の配列でオブジェクトのインデックスを要求できます。

NSArray *originalArray =  @[@"carrots", @"apple", @"dog", @"balle"];

NSLog(@"%@", originalArray);
[originalArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"%@ object at index %lu", obj, idx);
}];


NSArray *shuffledArray = [originalArray arrayShuffled];
 NSLog(@"%@", shuffledArray);
[shuffledArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"%@ object at index %lu %lu", obj, idx, [originalArray indexOfObject:obj]);
}];
于 2012-10-16T11:36:02.460 に答える
0

画像をシャッフルする必要がある2つの異なる画像配列があると仮定します。

 for(int i = 0; i <= 100; i++) 
    {
      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *documentsDir = [paths objectAtIndex:0];

        NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"[Images%d.png", i]]; 
        if([[NSFileManager defaultManager] fileExistsAtPath:savedImagePath]){ 
//Lazy initialization of dictionary 
            NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
            [dict setObject:[UIImage imageWithContentsOfFile:savedImagePath] forKey:@"items1"]; 
            [dict setObject:[NSNumber numberWithInt:i] forKey:@"index1"];
            [items1 addObject:dict]; 
    [dict release];          
        } 
    }

同じ方法でオブジェクトを 2 番目の配列に追加します。

NSUInteger count = [items1 count];
for(int i = 0 ;i < count; i++)
{
int nElements = count - i;
int n = (random() % nElements) + i;
[items1 exchangeObjectAtIndex:i withObjectAtIndex:n];
} 

2 番目の配列のシャッフル

 NSUInteger count = [items2 count];
    for(int i = 0 ;i < count; i++)
    {
    int nElements = count - i;
    int n = (random() % nElements) + i;
    [items2 exchangeObjectAtIndex:i withObjectAtIndex:n];
    } 

これはうまくいくはずです。それでも問題が解決しない場合は、お知らせください。

于 2012-10-16T06:22:36.850 に答える
0

アイデアが同じ順序で 2 つの配列をシャッフルすることであると仮定すると、最初の配列の直後に 2 番目の配列の交換を行うだけで済みますか?

NSUInteger count = [items1 count];
for (NSUInteger i = 0; i < count; ++i) {
    int nElements = count - i;
    int n = (random() % nElements) + i;
    [items1 exchangeObjectAtIndex:i withObjectAtIndex:n];
    [items2 exchangeObjectAtIndex:i withObjectAtIndex:n];
}
于 2012-10-16T04:11:41.047 に答える