Pertanyaan NSDictionary dengan tombol yang dipesan


Saya ingin tahu apakah ini adalah situasi yang orang lain temukan. Saya memiliki NSDictionary (disimpan dalam plist) yang pada dasarnya saya gunakan sebagai array asosiatif (string sebagai kunci dan nilai). Saya ingin menggunakan susunan kunci sebagai bagian dari aplikasi saya, tetapi saya ingin menggunakan susunan tertentu (tidak benar-benar suatu urutan yang dapat saya tulis algoritme untuk diurutkan menjadi). Saya selalu bisa menyimpan susunan kunci yang terpisah, tetapi sepertinya itu agak berantakan karena saya harus selalu memperbarui kunci-kunci kamus serta nilai-nilai larik, dan memastikannya selalu sesuai. Saat ini saya hanya menggunakan [myDictionary allKeys], tetapi jelas ini mengembalikannya dalam urutan yang tidak teratur dan tidak dijamin. Apakah ada struktur data di Objective-C yang saya lewatkan? Adakah yang punya saran tentang cara melakukan hal ini dengan lebih elegan?


76
2017-12-17 21:27


asal


Jawaban:


Solusi memiliki kunci NSMutableArray yang terkait tidak terlalu buruk. Ini menghindari subkode NSDictionary, dan jika Anda berhati-hati dengan akseptor menulis, seharusnya tidak terlalu sulit untuk tetap tersinkronisasi.


23
2017-12-17 22:19



Saya terlambat ke permainan dengan jawaban yang sebenarnya, tetapi Anda mungkin tertarik untuk menyelidiki CHOrderedDictionary. Ini adalah subkelas dari NSMutableDictionary yang merangkum struktur lain untuk mempertahankan urutan kunci. (Ini bagian dari CHDataStructures.framework.) Saya merasa lebih nyaman daripada mengelola kamus dan susunan secara terpisah.

Disclosure: Ini adalah kode open-source yang saya tulis. Hanya berharap itu mungkin berguna untuk orang lain menghadapi masalah ini.


18
2017-10-18 19:04



Tidak ada metode inbuilt dari mana Anda dapat memperoleh ini. Tetapi logika sederhana bekerja untuk Anda. Anda cukup menambahkan beberapa teks numerik di depan setiap tombol saat Anda mempersiapkan kamus. Seperti

NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:
                       @"01.Created",@"cre",
                       @"02.Being Assigned",@"bea",
                       @"03.Rejected",@"rej",
                       @"04.Assigned",@"ass",
                       @"05.Scheduled",@"sch",
                       @"06.En Route",@"inr",
                       @"07.On Job Site",@"ojs",
                       @"08.In Progress",@"inp",
                       @"09.On Hold",@"onh",
                       @"10.Completed",@"com",
                       @"11.Closed",@"clo",
                       @"12.Cancelled", @"can",
                       nil]; 

Sekarang jika Anda dapat menggunakan sortingArrayUsingSelector sambil mendapatkan semua kunci dalam urutan yang sama seperti yang Anda tempatkan.

NSArray *arr =  [[dict allKeys] sortedArrayUsingSelector:@selector(localizedStandardCompare:)];

Di tempat Anda ingin menampilkan kunci di UIView, hanya memotong 3 karakter depan.


15
2018-02-22 09:14



Jika Anda akan subkelas NSDictionary Anda perlu menerapkan metode ini sebagai minimum:

  • NSDictionary
    • -count
    • -objectForKey:
    • -keyEnumerator
  • NSMutableDictionary
    • -removeObjectForKey:
    • -setObject:forKey:
  • NSCopying / NSMutableCopying
    • -copyWithZone:
    • -mutableCopyWithZone:
  • NSCoding
    • -encodeWithCoder:
    • -initWithCoder:
  • NSFastEnumeration (untuk Leopard)
    • -countByEnumeratingWithState:objects:count:

Cara termudah untuk melakukan apa yang Anda inginkan adalah membuat subkelas dari NSMutableDictionary yang berisi 'NSMutableDictionary-nya sendiri yang dimanipulasikan dan NSMutableArray untuk menyimpan serangkaian tombol yang diurutkan.

Jika Anda tidak akan menyandikan objek Anda, Anda bisa saja melewatkan penerapan -encodeWithCoder: dan -initWithCoder:

Semua implementasi metode Anda dalam 10 metode di atas kemudian akan langsung masuk melalui kamus yang di-host atau susunan kunci yang Anda pesan.


7
2017-12-18 04:40



Penambahan kecil saya: menyortir berdasarkan kunci numerik (Menggunakan notasi singkat untuk kode yang lebih kecil)

// the resorted result array
NSMutableArray *result = [NSMutableArray new];
// the source dictionary - keys may be Ux timestamps (as integer, wrapped in NSNumber)
NSDictionary *dict =
@{
  @0: @"a",
  @3: @"d",
  @1: @"b",
  @2: @"c"
};

{// do the sorting to result
    NSArray *arr = [[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];

    for (NSNumber *n in arr)
        [result addObject:dict[n]];
}

5
2018-03-20 13:58



Cepat 'n kotor:

Ketika Anda perlu memesan kamus Anda (disini disebut "myDict"), lakukan ini:

     NSArray *ordering = [NSArray arrayWithObjects: @"Thing",@"OtherThing",@"Last Thing",nil];

Kemudian, ketika Anda perlu memesan kamus Anda, buat indeks:

    NSEnumerator *sectEnum = [ordering objectEnumerator];
    NSMutableArray *index = [[NSMutableArray alloc] init];
        id sKey;
        while((sKey = [sectEnum nextObject])) {
            if ([myDict objectForKey:sKey] != nil ) {
                [index addObject:sKey];
            }
        }

Sekarang, objek indeks * akan berisi kunci yang sesuai dalam urutan yang benar. Perhatikan bahwa solusi ini tidak mengharuskan semua kunci harus ada, yang merupakan situasi yang biasa kita hadapi ...


3
2017-08-13 03:47



Untuk, Swift 3. Silakan mencoba pendekatan berikut

        //Sample Dictionary
        let dict: [String: String] = ["01.One": "One",
                                      "02.Two": "Two",
                                      "03.Three": "Three",
                                      "04.Four": "Four",
                                      "05.Five": "Five",
                                      "06.Six": "Six",
                                      "07.Seven": "Seven",
                                      "08.Eight": "Eight",
                                      "09.Nine": "Nine",
                                      "10.Ten": "Ten"
                                     ]

        //Print the all keys of dictionary
        print(dict.keys)

        //Sort the dictionary keys array in ascending order
        let sortedKeys = dict.keys.sorted { $0.localizedCaseInsensitiveCompare($1) == ComparisonResult.orderedAscending }

        //Print the ordered dictionary keys
        print(sortedKeys)

        //Get the first ordered key
        var firstSortedKeyOfDictionary = sortedKeys[0]

        // Get range of all characters past the first 3.
        let c = firstSortedKeyOfDictionary.characters
        let range = c.index(c.startIndex, offsetBy: 3)..<c.endIndex

        // Get the dictionary key by removing first 3 chars
        let firstKey = firstSortedKeyOfDictionary[range]

        //Print the first key
        print(firstKey)

2
2017-10-19 12:25



Implementasi minimal dari subkelas dari NSDictionary (berdasarkan https://github.com/nicklockwood/OrderedDictionary). Jangan ragu untuk memperpanjang untuk kebutuhan Anda:

Swift 3 dan 4

class MutableOrderedDictionary: NSDictionary {
    let _values: NSMutableArray = []
    let _keys: NSMutableOrderedSet = []

    override var count: Int {
        return _keys.count
    }
    override func keyEnumerator() -> NSEnumerator {
        return _keys.objectEnumerator()
    }
    override func object(forKey aKey: Any) -> Any? {
        let index = _keys.index(of: aKey)
        if index != NSNotFound {
            return _values[index]
        }
        return nil
    }
    func setObject(_ anObject: Any, forKey aKey: String) {
        let index = _keys.index(of: aKey)
        if index != NSNotFound {
            _values[index] = anObject
        } else {
            _keys.add(aKey)
            _values.add(anObject)
        }
    }
}

pemakaian

let normalDic = ["hello": "world", "foo": "bar"]
// initializing empty ordered dictionary
let orderedDic = MutableOrderedDictionary()
// copying normalDic in orderedDic after a sort
normalDic.sorted { $0.0.compare($1.0) == .orderedAscending }
         .forEach { orderedDic.setObject($0.value, forKey: $0.key) }
// from now, looping on orderedDic will be done in the alphabetical order of the keys
orderedDic.forEach { print($0) }

Objective-C

@interface MutableOrderedDictionary<__covariant KeyType, __covariant ObjectType> : NSDictionary<KeyType, ObjectType>
@end
@implementation MutableOrderedDictionary
{
    @protected
    NSMutableArray *_values;
    NSMutableOrderedSet *_keys;
}

- (instancetype)init
{
    if ((self = [super init]))
    {
        _values = NSMutableArray.new;
        _keys = NSMutableOrderedSet.new;
    }
    return self;
}

- (NSUInteger)count
{
    return _keys.count;
}

- (NSEnumerator *)keyEnumerator
{
    return _keys.objectEnumerator;
}

- (id)objectForKey:(id)key
{
    NSUInteger index = [_keys indexOfObject:key];
    if (index != NSNotFound)
    {
        return _values[index];
    }
    return nil;
}

- (void)setObject:(id)object forKey:(id)key
{
    NSUInteger index = [_keys indexOfObject:key];
    if (index != NSNotFound)
    {
        _values[index] = object;
    }
    else
    {
        [_keys addObject:key];
        [_values addObject:object];
    }
}
@end

pemakaian

NSDictionary *normalDic = @{@"hello": @"world", @"foo": @"bar"};
// initializing empty ordered dictionary
MutableOrderedDictionary *orderedDic = MutableOrderedDictionary.new;
// copying normalDic in orderedDic after a sort
for (id key in [normalDic.allKeys sortedArrayUsingSelector:@selector(compare:)]) {
    [orderedDic setObject:normalDic[key] forKey:key];
}
// from now, looping on orderedDic will be done in the alphabetical order of the keys
for (id key in orderedDic) {
    NSLog(@"%@:%@", key, orderedDic[key]);
}

1
2017-09-06 14:15