2016-04-21 5 views
0

Название может быть путаным, извинения. Может быть, кто-то может посоветовать мне более подходящий титул.Создать словарь со словарями массивов (отсортировано по определенному свойству пользовательского объекта)?

У меня есть файл .json, структурированный, как показано ниже.

"sections": [{ 
      "title": "Locations", 
      "key": "location" 
      }], 
"contacts": [{ 
      "title": "Social Worker", 
      "name": "Mrs X", 
      "office": "xxxxxxxx", 
      "location": "Lisburn", 
      "department": "xxxxxxxx", 
      "telephone": "xxx xxxxxxxx" 
      },... 

При анализе этого я создать array называется contactsArray. Затем я могу создать AEContact объекты этого array так:

for (NSDictionary *contactDic in [contactsArray valueForKey:@"contacts"]) { 
    // Create AEContact objects 
    _contact = [[AEContact alloc] initWithDictionary:contactDic]; 
    [contacts addObject:_contact]; 
} 
self.contacts = [contacts copy]; 

В self.contactsarray, то value для contact.location собственности, что я заинтересован в мне нужно создать отдельный arrays связанных AEContact объектов на основе. location свойство, то отобразить их в locationkey в моем contactArraydictionary

Это то, что я пытался до сих пор:

NSMutableDictionary *locationsDic = [NSMutableDictionary new]; 
// Loop through contacts 
for (int i = 0; i < self.contacts.count; i++) { 
    // Sort by location 
    if ([self.contacts[i] valueForKey:@"location"] == [[[contactsArray valueForKey:@"contacts"] objectAtIndex:i] valueForKey:@"location"]) { 
     [locationsDic setValue:self.contacts[i] forKey:[[[contactsArray valueForKey:@"contacts"] objectAtIndex:i] valueForKey:@"location"]]; 
    } 
} 

И выход:

{ 
    Ballynahinch = "<AEContact: 0x15dda1fc0>"; 
    Bangor = "<AEContact: 0x15dda2210>"; 
    Lisburn = "<AEContact: 0x15dda1c70>"; 
    ... 
} 

Когда AEContact объект имеет тот же location, он устанавливает его как еще один ключ/значение в словаре и перезаписывает предыдущую запись. Что мне нужно, чтобы это произошло что-то вроде этого:

{ 
    Lisburn = "<AEContact: 0x15dda18f0>", 
       "<AEContact: 0x15dda18f0>", 
       "<AEContact: 0x15dda18f0>"; 

    Bangor = "<AEContact: 0x15dda18f0>", 
      "<AEContact: 0x15dda18f0>", 
      "<AEContact: 0x15dda18f0>"; 
} 

Я не уверен, если выход должен должен/будет выглядеть предварительный просмотр выше, я могу только предположить, как я еще не достиг своей цели. Как создать связанные объекты AEContact в array и сопоставить их с location ключом в моем locationsDic? Благодарю.

+1

вы не можете иметь несколько значений для одного ключа. Один ключ и одно значение для словаря. У вас может быть массив значений в качестве значения для ключа. –

+0

Хорошо, что имеет смысл. Любые идеи о том, как я могу создать массив значений для ключа? Я не ожидаю, что вы напишите мне кучу кода, но даже если вы можете указать мне в правильном направлении по некоторым ссылкам? В идеале, как можно ближе к моей проблеме. Спасибо, что нашли время для чтения. – rosshump

+1

Я смущен ur для цикла. Я думаю, вы должны добавить объекты в массив здесь, для цикла. И после завершения цикла for вы можете добавить этот массив в словарь. –

ответ

1

Название (и описание проблемы) немного сложно выполнить, но я думаю, вы пытаетесь индексировать массив объектов (AEContact) по их параметру местоположения.

Мы можем прояснить это только с помощью более жесткого именования и с помощью шаблона поиска или создания при обработке ввода.

NSDictionary *jsonResult = // the dictionary you begin with 
NSArray *contactParams = jsonResult[@"contacts"]; 
NSMutableDictionary *contactsByLocation = [@{} mutableCopy]; 

for (NSDictionary *contactParam in contactParams) { 
    NSString *location = contactParam[@"location"]; 

    // here's the important part: find the array of aecontacts in our indexed result, or 
    // create it if we don't find it 
    NSMutableArray *aeContacts = contactsByLocation[location]; 
    if (!aeContacts) { 
     aeContacts = [@[] mutableCopy]; 
     contactsByLocation[location] = aeContacts; 
    } 
    AEContact *aeContact = [[AEContact alloc] initWithDictionary:contactParam]; 
    [aeContacts addObject:aeContact]; 
} 

contactsByLocation будет то, что я думаю, что вы ищете.

+0

Много извинений о названии и описании, но вы были в поиске того, чего я пытался достичь. Ваш код работает отлично и точно, что мне нужно! 'contactsByLocation' - это словарь, который мне нужен. Я точно изучу, как вы это достигли, потому что это идеально подходит для моей ситуации. Я весь день стучал головой, пытаясь реализовать это. Большое спасибо! :) – rosshump

+1

рад помочь. я просто заметил ошибку в коде, который я предложил. см. править. – danh

+0

Ах да, после нескольких прогонов я заметил, что отсутствует один объект AEContact для каждого массива. Я как раз собирался попытаться исправить ошибку самостоятельно, возможно, это заняло бы у меня некоторое время, поэтому я только что вернул назад, и вы редактируете сейчас безупречно. Еще раз спасибо человеку, очень ценю помощь! – rosshump