NSDictionary按字母顺序排序 [英] NSDictionary getting sorted alphabetically

查看:70
本文介绍了NSDictionary按字母顺序排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将NSDictionary作为参数传递给我的函数.我希望它的键和值在插入时按顺序排列. 例如预期输出为:

 mutable dict:{
            zKey1 = Value1;
            fKey2 = Value2;
            aKey3 = Value3;
        } 

我尝试了以下方法来创建和设置键值.

    NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc]init];
        [mutableDict setObject:@"Value1" forKey:@"zKey1"];
        [mutableDict setObject:@"Value2" forKey:@"fKey2"];
        [mutableDict setObject:@"Value3" forKey:@"aKey3"];

    NSMutableDictionary *dic2=[[NSMutableDictionary alloc]initWithObjectsAndKeys:@"1004",@"userId",@"cucumber",@"domain",@"168d5c02f ",@"token",@"1004",@"userId1",@"cucumber",@"domain1",@"168d5c02f ",@"token1", nil];


    NSDictionary * dict = [NSDictionary
                               dictionaryWithObjects:@[@"Ravi",@"33",@"India",@"India"]
                               forKeys:@[@"name",@"age",@"location",@"country"]];
        NSArray *sortedKeys = [[dict allKeys] sortedArrayUsingSelector: @selector(compare:)];

        NSMutableArray *sortedValues = [NSMutableArray array];
        for (NSString *key in sortedKeys) {
            [sortedValues addObject: [dict objectForKey: key]];
        }

    NSString *obj1=@"1004";
        NSString *obj2=@"cucumber";
        NSString *obj3=@"168d5c02f";

        NSString *key1=@" userId";
        NSString *key2=@"domain";
        NSString *key3=@"token";
        NSLog(@"dict %@",dict);

        NSDictionary *dict8 =[NSDictionary
                              dictionaryWithObjects:@[obj1,obj2,obj3]
                              forKeys:@[key1,key2,key3]];

但是没有任何效果,我总是得到

    mutable dict:{
        aKey3 = Value3;
        fKey2 = Value2;
        zKey1 = Value1;
    } 


    dict8 {
        domain = cucumber;
        token = 168d5c02f;
        userId = 1004;
    }

     dict {
        age = 33;
        country = India;
        location = India;
        name = Ravi;
    }

    dic= {
        domain = cucumber;
        domain1 = cucumber;
        token = "168d5c02f ";
        token1 = "168d5c02f ";
        userId = 1004;
        userId1 = 1004;
    }

它总是根据键的字母顺序对值进行排序.许多人说NSDictionary是未分类的容器.但是它确实得到了排序.迫切需要帮助.预先谢谢你.

解决方案

NSDictionary默认为未排序.它将永远没有任何顺序.要创建有序字典,您将需要覆盖Data结构的现有形式.您可以阅读本教程以达到最终目的.

总结本教程(因为每个人都讨厌仅链接的答案,链接随时可能消失):

NSDictionary将其密钥存储在哈希表中,该哈希表在设计上没有顺序.由于缺乏顺序是哈希表存储的基础,因此您必须执行NSMutableDictionary的子类化(并因此重新实现存储).

在您的.h文件中

//
//  OrderedDictionary.h
//  OrderedDictionary
//
//  Created by Matt Gallagher on 19/12/08.
//  Copyright 2008 Matt Gallagher. All rights reserved.
//
//  Permission is given to use this source code file without charge in any
//  project, commercial or otherwise, entirely at your risk, with the condition
//  that any redistribution (in part or whole) of source code must retain
//  this copyright and permission notice. Attribution in compiled projects is
//  appreciated but not required.
//

#import <Cocoa/Cocoa.h>

@interface OrderedDictionary : NSMutableDictionary
{
    NSMutableDictionary *dictionary;
    NSMutableArray *array;
}

- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex;
- (id)keyAtIndex:(NSUInteger)anIndex;
- (NSEnumerator *)reverseKeyEnumerator;

@end

在您的.m文件中:

//
//  OrderedDictionary.m
//  OrderedDictionary
//
//  Created by Matt Gallagher on 19/12/08.
//  Copyright 2008 Matt Gallagher. All rights reserved.
//
//  Permission is given to use this source code file without charge in any
//  project, commercial or otherwise, entirely at your risk, with the condition
//  that any redistribution (in part or whole) of source code must retain
//  this copyright and permission notice. Attribution in compiled projects is
//  appreciated but not required.
//

#import "OrderedDictionary.h"

NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent)
{
    NSString *objectString;
    if ([object isKindOfClass:[NSString class]])
    {
        objectString = (NSString *)[[object retain] autorelease];
    }
    else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)])
    {
        objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent];
    }
    else if ([object respondsToSelector:@selector(descriptionWithLocale:)])
    {
        objectString = [(NSSet *)object descriptionWithLocale:locale];
    }
    else
    {
        objectString = [object description];
    }
    return objectString;
}

@implementation OrderedDictionary

- (id)init
{
    return [self initWithCapacity:0];
}

- (id)initWithCapacity:(NSUInteger)capacity
{
    self = [super init];
    if (self != nil)
    {
        dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
        array = [[NSMutableArray alloc] initWithCapacity:capacity];
    }
    return self;
}

- (void)dealloc
{
    //This method is pre-ARC. Manual Release commands don't work now. 
    //[dictionary release]; 
    //[array release];
    //[super dealloc];
}

- (id)copy
{
    return [self mutableCopy];
}

- (void)setObject:(id)anObject forKey:(id)aKey
{
    if (![dictionary objectForKey:aKey])
    {
        [array addObject:aKey];
    }
    [dictionary setObject:anObject forKey:aKey];
}

- (void)removeObjectForKey:(id)aKey
{
    [dictionary removeObjectForKey:aKey];
    [array removeObject:aKey];
}

- (NSUInteger)count
{
    return [dictionary count];
}

- (id)objectForKey:(id)aKey
{
    return [dictionary objectForKey:aKey];
}

- (NSEnumerator *)keyEnumerator
{
    return [array objectEnumerator];
}

- (NSEnumerator *)reverseKeyEnumerator
{
    return [array reverseObjectEnumerator];
}

- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex
{
    if (![dictionary objectForKey:aKey])
    {
        [self removeObjectForKey:aKey];
    }
    [array insertObject:aKey atIndex:anIndex];
    [dictionary setObject:anObject forKey:aKey];
}

- (id)keyAtIndex:(NSUInteger)anIndex
{
    return [array objectAtIndex:anIndex];
}

- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
    NSMutableString *indentString = [NSMutableString string];
    NSUInteger i, count = level;
    for (i = 0; i < count; i++)
    {
        [indentString appendFormat:@"    "];
    }

    NSMutableString *description = [NSMutableString string];
    [description appendFormat:@"%@{\n", indentString];
    for (NSObject *key in self)
    {
        [description appendFormat:@"%@    %@ = %@;\n",
            indentString,
            DescriptionForObject(key, locale, level),
            DescriptionForObject([self objectForKey:key], locale, level)];
    }
    [description appendFormat:@"%@}\n", indentString];
    return description;
}

@end

您可以下载马特·加拉格尔的 orderedDictionary

But nothing has worked I am always getting output as

    mutable dict:{
        aKey3 = Value3;
        fKey2 = Value2;
        zKey1 = Value1;
    } 


    dict8 {
        domain = cucumber;
        token = 168d5c02f;
        userId = 1004;
    }

     dict {
        age = 33;
        country = India;
        location = India;
        name = Ravi;
    }

    dic= {
        domain = cucumber;
        domain1 = cucumber;
        token = "168d5c02f ";
        token1 = "168d5c02f ";
        userId = 1004;
        userId1 = 1004;
    }

It is always sorting values according to alphabetical order of keys. Many people say that NSDictionary is an unsorted container. But it does gets sorted. Need help desperately. Thank you in advance.

NSDictionary is not ordered by default. It will always be without any order. To create an ordered dictionary, you will need to override the existing form of the Data structure. You can read This tutorial to achieve your end.

To summarize the tutorial (Because everyone hates link-only answers and links can die any time):

NSDictionary stores its keys in a hash table, which is unordered by design. Since this lack of order is fundamental to the hash table storeage, you have to perform subclassing of NSMutableDictionary (and hence reimplementation of the storage).

In your .h file

//
//  OrderedDictionary.h
//  OrderedDictionary
//
//  Created by Matt Gallagher on 19/12/08.
//  Copyright 2008 Matt Gallagher. All rights reserved.
//
//  Permission is given to use this source code file without charge in any
//  project, commercial or otherwise, entirely at your risk, with the condition
//  that any redistribution (in part or whole) of source code must retain
//  this copyright and permission notice. Attribution in compiled projects is
//  appreciated but not required.
//

#import <Cocoa/Cocoa.h>

@interface OrderedDictionary : NSMutableDictionary
{
    NSMutableDictionary *dictionary;
    NSMutableArray *array;
}

- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex;
- (id)keyAtIndex:(NSUInteger)anIndex;
- (NSEnumerator *)reverseKeyEnumerator;

@end

In your .m file:

//
//  OrderedDictionary.m
//  OrderedDictionary
//
//  Created by Matt Gallagher on 19/12/08.
//  Copyright 2008 Matt Gallagher. All rights reserved.
//
//  Permission is given to use this source code file without charge in any
//  project, commercial or otherwise, entirely at your risk, with the condition
//  that any redistribution (in part or whole) of source code must retain
//  this copyright and permission notice. Attribution in compiled projects is
//  appreciated but not required.
//

#import "OrderedDictionary.h"

NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent)
{
    NSString *objectString;
    if ([object isKindOfClass:[NSString class]])
    {
        objectString = (NSString *)[[object retain] autorelease];
    }
    else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)])
    {
        objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent];
    }
    else if ([object respondsToSelector:@selector(descriptionWithLocale:)])
    {
        objectString = [(NSSet *)object descriptionWithLocale:locale];
    }
    else
    {
        objectString = [object description];
    }
    return objectString;
}

@implementation OrderedDictionary

- (id)init
{
    return [self initWithCapacity:0];
}

- (id)initWithCapacity:(NSUInteger)capacity
{
    self = [super init];
    if (self != nil)
    {
        dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
        array = [[NSMutableArray alloc] initWithCapacity:capacity];
    }
    return self;
}

- (void)dealloc
{
    //This method is pre-ARC. Manual Release commands don't work now. 
    //[dictionary release]; 
    //[array release];
    //[super dealloc];
}

- (id)copy
{
    return [self mutableCopy];
}

- (void)setObject:(id)anObject forKey:(id)aKey
{
    if (![dictionary objectForKey:aKey])
    {
        [array addObject:aKey];
    }
    [dictionary setObject:anObject forKey:aKey];
}

- (void)removeObjectForKey:(id)aKey
{
    [dictionary removeObjectForKey:aKey];
    [array removeObject:aKey];
}

- (NSUInteger)count
{
    return [dictionary count];
}

- (id)objectForKey:(id)aKey
{
    return [dictionary objectForKey:aKey];
}

- (NSEnumerator *)keyEnumerator
{
    return [array objectEnumerator];
}

- (NSEnumerator *)reverseKeyEnumerator
{
    return [array reverseObjectEnumerator];
}

- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex
{
    if (![dictionary objectForKey:aKey])
    {
        [self removeObjectForKey:aKey];
    }
    [array insertObject:aKey atIndex:anIndex];
    [dictionary setObject:anObject forKey:aKey];
}

- (id)keyAtIndex:(NSUInteger)anIndex
{
    return [array objectAtIndex:anIndex];
}

- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
    NSMutableString *indentString = [NSMutableString string];
    NSUInteger i, count = level;
    for (i = 0; i < count; i++)
    {
        [indentString appendFormat:@"    "];
    }

    NSMutableString *description = [NSMutableString string];
    [description appendFormat:@"%@{\n", indentString];
    for (NSObject *key in self)
    {
        [description appendFormat:@"%@    %@ = %@;\n",
            indentString,
            DescriptionForObject(key, locale, level),
            DescriptionForObject([self objectForKey:key], locale, level)];
    }
    [description appendFormat:@"%@}\n", indentString];
    return description;
}

@end

You can Download Matt Gallagher's orderedDictionary here.

这篇关于NSDictionary按字母顺序排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆