2017-01-23 6 views
1

Я борюсь с преобразованием форматов для словарей: Я пытаюсь преобразовать массив элементов ниже в массив результатов ниже. По существу, просматривая дубликаты в элементе first element, а затем добавляя файлы к набору результатов, когда первый параметр отличается.Swift: Преобразование

var items:[[String]] = [["a", "b"],["a", "c"],["b", "c"]] 

var result:[[String:[String]]] = [ 
    ["a":["b","c"]], 
    ["b":["c"]] 
] 

Я попытался использовать множество массивов, однако я продолжаю сталкиваться с ошибками в своем xcode. Любая идея, какой будет лучший подход?

Цикл for in, как представляется, подходит для одного предмета. Помощь будет высоко оценена.

+0

ли результаты должны быть массивом, или это просто словарь. var result: [String: [String]] = [ "a": ["b", "c"], "b": ["c"] ]? – ptoinson

+0

На самом деле словарь тоже будет работать –

+0

Почему у вас есть структура данных, состоящая из 2 массивов элементов? Что-то кажется подозрительным ... – Alexander

ответ

0

Я предполагаю, что общий случай, когда к югу массивы элемента может иметь более чем на строку. Это также позволяет создавать пустые массивы в массиве items. Это дает результаты [ "а": [ "B", "C", "г"], "Ъ": [ "с"], "C": []]

func testThree() { 
    let items = [["a", "b"],["a", "c", "g"],["b", "c"],["c"]] 
    var result:[String:[String]] = [:] 

    for arr in items { 
     if(arr.count > 0) { 
      let first = arr[0] 
      if(result[first] != nil) { 
       result[first]!.append(contentsOf: arr[1..<arr.count]) 
      } else { 
       result[first] = Array(arr[1..<arr.count]) 
      } 
     } 
    } 
} 
+0

Почему все аннотации избыточного типа? – Alexander

+0

Нет причин. Удалите их, если хотите. – ptoinson

+0

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

0

Если result может быть словарем - как вы упомянули в своем комментарии - вы можете сделать это:

var result = [String:[String]]() 
items.forEach { 
    if let entry = result[$0[0]] { 
     result[$0[0]]?.append($0[1]) 
    } else { 
     result[$0[0]] = [$0[1]] 
    } 
} 

Ради удобства чтения можно также записать как:

var result = [String:[String]]() 
for item in items { 
    if let entry = result[item[0]] { 
     result[item[0]]?.append(item[1]) 
    } else { 
     result[item[0]] = [item[1]] 
    } 
} 

items.forEach {...} в основном делает то же самое, что и обычный цикл for..in, только без именованной переменной (в данном случае item), поэтому вам нужно будет получить доступ к текущему значению с помощью $0.

Результатом этого кода будет

["a": ["b", "c"], "b": ["c"]] 
+0

Спасибо, что я не знаком с элементами. Перед синтаксисом - позаботьтесь о том, чтобы объяснить это в несколько более упрощенных терминах или ссылку на то, где я могу прочитать об этом? –

+0

@MobileBloke Я добавил эквивалентную альтернативу (которую я бы предпочел сам) и связался с документацией для функции 'forEach (_ :)'. – Keiwan

Смежные вопросы