Код Swift: как создать словарь массива строк на основе нулевой записи словаря

Я пытался понять, как делать некоторые простые вещи со Swift, используя типы Dictionary и Array.

Я начал с попытки написать приведенные ниже простые функции для управления списком строк и объединения их в один и тот же массив, когда строки являются анаграммами друг друга..!

Все здесь должно работать на игровой площадке в Xcode.

Вопросы:

  1. Почему я не могу использовать toString() для преобразования массива символов в строку. Мне нужно перебрать массив символов и построить строку, используя += ?
  2. Каков наилучший способ добавить массив в словарь на лету, поскольку я обнаружил, что словарь пуст для этого строкового индекса, поэтому мне нужно создать новый массив для хранения строк, которые содержат одни и те же буквы. Путаница из-за того, что словарь не содержит типы, которые вы думаете, но на самом деле содержит тип? (это тип опции - в моем случае String?, необязательная строка).

Смотрите сумасшедший код ниже.

groupAnagrams(
  listofWords: pass an array of String (immutable)
 )

возвращает Словарь массива строк (сгруппированные анаграммы) Сводка количества действий, выполненных в массиве строк Журнал действий, выполненных в массиве строк

Цель Сгруппировать слова, являющиеся анаграммами, в сегменты Функция func создаст словарь, индексированный по строке, которая представляет собой упорядоченную строку символов, например ["летучие мыши", "удар"] => ["воздержание" : ["крысы", "удар"] ]

Функция charArrayToString

func charArrayToString(charArray ca: [Character]) -> String {
    var s = ""
    for c in ca {
        s += String(c)
    }
    return s
}

func groupAnagrams(#listOfWords: [String]) -> [String:[String]] {
    var s = ""
    var d: [String:[String]] = [String:[String]]()
    var i = 0, j = 0, k = 0
    var log = [String]()

    for s in listOfWords {
        var s1:[Character] = [Character](s)
        //    var s1 = s
        sort(&s1) { (a: Character, b: Character) -> Bool in return String(a) < String(b) }
//???        var s2 = toString(s1) // converts the Array of Character to a string (but it's for the for "[a,b,c,d]" and not "abcd" as you'd expect!
        var s3 = charArrayToString(charArray: s1)
        // Array already exists, add a string ELSE create the String array [String]() and add the fisst element
        if let p = d[s3] {
            // Array exists but d[s3] is "immutable" as it's optional array of String (type [String]?)
            ++i
            var arr = d[s3]!
            arr += [s]
            d[s3] = arr
            log += "Add string \(arr.count) \(s) to array \(s3) \n"
        } else {
            // ELSE: Create new String array
            ++j
            d[s3] = [String]()
            var arr = d[s3]!
            arr += [s]
            d[s3] = arr
            log += "Create array for \(s3) with string \(s) \n"
        }
        ++k
        //    break
    }


    var summary = [String]()
    summary += ["\(i) strings added to already created arrays"]
    summary += ["\(j) arrays created"]
    summary += ["\(k) words processed"]

    summary[0] // inspect
    summary[1] // inspect
    summary[2] // inspect

    log // inspect

    return d
}

// То же, что и версия функции с массивом, но просто добавляет строки в список параметров функции

func groupAnagramsList(strings: String...) -> [String:[String]] {
    return groupAnagrams(listOfWords: strings)
}

Вызовы различных созданных функций:

var listOfWords = [String]() + ["bats", "star", "tree", "stab", "rats", "reet", "pong", "peel", "leep", "path", "type", "pyte", "ypte"]

var anagrams = groupAnagrams(listOfWords: listOfWords)

var otherWay = groupAnagramsList("bats", "star", "tree", "stab", "rats", "reet", "pong", "peel", "leep", "path", "type", "pyte", "ypte")

ОБНОВЛЕНИЕ ИЗ Swift Beta 5:

if d[s3] == nil {
    d[s3] = [String]()
    ++j
} else {
    ++i
}
d[s3]! += [s]
log += ["Add string \(d[s3]!.count) \(s) to array \(s3) \n"]

Проверка на ноль в словаре d действительна! В этом контексте сложное необязательное/неизменяемое поведение исчезло, и код стал намного проще для понимания. Примечание: мне пришлось изменить

log += "Добавить строку (d[s3]!.count) (s) в массив (s3) \n"

To:

log += ["Добавить строку (d[s3]!.count) (s) в массив (s3) \n"]

Потому что теперь вам нужно явно добавить массив строк в массив строк. Вы не можете предположить, что += в строке добавит строку в массив. Но это легко, просто оберните строку в '[' и ']'.

Я до сих пор не знаю, почему я не могу просто преобразовать массив символов в строку!


person CPD    schedule 15.08.2014    source источник


Ответы (1)


Возможно, было бы разумно использовать встроенные в Swift API-интерфейсы Objective-C для устранения повторяющихся значений. Например:

let unique = NSSet(array: swiftArrayOfNonUniqueStrings).allObjects

Проблема в том, что применение этого к вашему отсортированному по символам массиву строк, содержащему дубликаты, просто вернет отсортированную по символам версию вашей исходной строки. (Вы можете получить такой массив, вернув alphaList ниже.)

Что касается сортировки символов в строке, я считаю, что итерация символов для построения строки достаточно эффективна. Вы можете написать это немного короче

func alphabetizeStrings(list : [String]) -> [String] {   
    var newlist = [String]()
    var alphaList = [String]()
    for s in list {
        var charArray = [Character](s)
        charArray.sort({ (a: Character, b: Character) -> Bool in return String(a) < String(b)})
        var sortedString = ""
        for c in charArray {
            sortedString += c
        }
        if NSArray(array: alphaList).containsObject(sortedString) == false {
            newlist.append(s)
        }
        alphaList.append(sortedString)
    }
    return newlist
}

Таким образом:

let swiftarray = ["foo", "foo", "bar", "bra", "bat"]
let unique = alphabetizeStrings(swiftarray)
// ["foo", "bar", "bat"]
person Mundi    schedule 15.08.2014