NSDictionary 按字母顺序排序[重复]

Posted

技术标签:

【中文标题】NSDictionary 按字母顺序排序[重复]【英文标题】:NSDictionary getting sorted alphabetically [duplicate] 【发布时间】:2016-03-11 07:13:26 【问题描述】:

我将 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 默认不排序。它将永远没有任何顺序。要创建有序字典,您需要覆盖数据结构的现有形式。你可以阅读This tutorial来达到你的目的。 不,即使您按顺序添加它们,它也不是“按键排序”的 NSDictionary。如果输出是按顺序的,那只是你走运了。您可以通过排序键 NSArray 枚举具有所需顺序的键来打印它们,但不能直接使用 NSDictionary 本身。 为什么不使用 NSMutableArray ?语法也很简单..@[@"key1":value1,@"key2":value2,@"key3":value3] 但是我没有按顺序得到输出。它始终根据键按字母顺序排序。如图所示。 【参考方案1】:

NSDictionary 默认情况下未排序。它将永远没有任何顺序。要创建有序字典,您需要覆盖数据结构的现有形式。你可以阅读This tutorial来达到你的目的。

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

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

您可以下载Matt Gallagher'sorderedDictionaryhere。

【讨论】:

该代码是 ARC 之前的代码!它需要一些工作来使其现代化 @Paulw11 工作量并不大,您只需删除dealloc() 方法。我没有删除它,因为它不是我的代码。我认为当 xcode 在release 命令处给他一个错误时,OP 会很明显。 @NSNoob:成功了。

以上是关于NSDictionary 按字母顺序排序[重复]的主要内容,如果未能解决你的问题,请参考以下文章

java按字母顺序排序[重复]

Jquery排序 - 按字母顺序排列图像[重复]

按字母顺序对 NSMutableArray 进行排序[重复]

按字母顺序对HashMap程序的输出进行排序[重复]

表格视图从 NSDictionary 加载,但不按字母顺序

如何通过删除名称开头的数字按字母顺序对数据进行排序[重复]