Swift: sort [String: String] () с помощью клавиши [duplicate]

Я нашел хак через DECLARE CONTINUE HANDLER и GET DIAGNOSTICS CONDITION, поэтому просто подумал, я должен поделиться им здесь.

Вот мой полный финальный скрипт, который сохраняет резервную копию (синхронизацию) для обеих баз данных users что это означает, что любое обновление на test_db1 (которое мы можем назвать его производным DB) будет происходить на test_db2 (которое мы можем назвать его как stagingDB):

/*
Create two databases:
    1. `test_db1`
    2. `test_db2`
and execute below create *Table script* on both databases.
after that execute *Triggers Script* on `test_db1` only..
*/

/*
    TABLE STRUCTURE FOR `users`
*/

DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) AUTO_INCREMENT NOT NULL,
  `name` varchar(30) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

/*
    TABLE STRUCTURE FOR `errors`
*/

DROP TABLE IF EXISTS `errors`;
CREATE TABLE IF NOT EXISTS `errors` (
  `id` int(11) AUTO_INCREMENT NOT NULL,
  `code` varchar(30) NOT NULL,
  `message` TEXT NOT NULL,
  `query_type` varchar(50) NOT NULL,
  `record_id` int(11) NOT NULL,
  `on_db` varchar(50) NOT NULL,
  `on_table` varchar(50) NOT NULL,
  `emailed` TINYINT DEFAULT 0,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

/*
    TRIGGERS SCRIPTS FOR INSERT, UPDATE AND DELETE OPERATIONS
*/

DELIMITER //

-- TRIGGER FOR INSERT
DROP TRIGGER IF EXISTS `test_db1_users_ai`;
CREATE TRIGGER `test_db1_users_ai` AFTER INSERT ON `users` FOR EACH ROW 
BEGIN
    -- Declare variables to hold diagnostics area information
    DECLARE errorCode CHAR(5) DEFAULT '00000';
    DECLARE errorMessage TEXT DEFAULT '';

    -- Declare exception handler for failed insert
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
    BEGIN
      GET DIAGNOSTICS CONDITION 1
        errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
    END;

    -- Perform the insert
    INSERT INTO `test_db2`.`users` (id, name, age) VALUES (NEW.id, NEW.name, NEW.age);

    -- Check whether the insert was successful
    IF errorCode != '00000' THEN
        INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'insert', NEW.id, 'test_db2', 'users');
    END IF;
END; //

-- TRIGGER FOR UPDATE
DROP TRIGGER IF EXISTS `test_db1_users_au`;
CREATE TRIGGER `test_db1_users_au` AFTER UPDATE ON `users` FOR EACH ROW 
BEGIN
    -- Declare variables to hold diagnostics area information
    DECLARE errorCode CHAR(5) DEFAULT '00000';
    DECLARE errorMessage TEXT DEFAULT '';

    -- Declare exception handler for failed insert
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
    BEGIN
      GET DIAGNOSTICS CONDITION 1
        errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
    END;

    -- Perform the update
    UPDATE `test_db2`.`users`
        SET name = NEW.name,
            age = NEW.age
        WHERE id = NEW.id;

    -- Check whether the update was successful
    IF errorCode != '00000' THEN
        INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'update', NEW.id, 'test_db2', 'users');
    END IF;
END; //

-- TRIGGER FOR DELETE
DROP TRIGGER IF EXISTS `test_db1_users_ad`;
CREATE TRIGGER `test_db1_users_ad` AFTER DELETE ON `users` FOR EACH ROW 
BEGIN
    -- Declare variables to hold diagnostics area information
    DECLARE errorCode CHAR(5) DEFAULT '00000';
    DECLARE errorMessage TEXT DEFAULT '';

    -- Declare exception handler for failed insert
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
    BEGIN
      GET DIAGNOSTICS CONDITION 1
        errorCode = RETURNED_SQLSTATE, errorMessage = MESSAGE_TEXT;
    END;

    -- Perform the delete
    DELETE FROM `test_db2`.`users`
        WHERE id = OLD.id;

    -- Check whether the insert was successful
    IF errorCode != '00000' THEN
        INSERT INTO `errors` (code, message, query_type, record_id, on_db, on_table) VALUES (errorCode, errorMessage, 'delete', OLD.id, 'test_db2', 'users');
    END IF;
END; //

-- DELIMITER;

Hope это поможет другим, когда они придут сюда.

Приветствия,

92
задан Dan Beaulieu 25 November 2015 в 03:23
поделиться

10 ответов

let dictionary = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

let sortedKeys = Array(dictionary.keys).sorted(<) // ["A", "D", "Z"]

EDIT:

Сортированный массив из приведенного выше кода содержит только ключи, а значения должны быть получены из исходного словаря. Однако 'Dictionary' также является 'CollectionType' парами (ключ, значение), и мы можем использовать глобальную функцию 'sorted', чтобы получить отсортированный массив, содержащий оба ключа и значения, например:

let sortedKeysAndValues = sorted(dictionary) { $0.0 < $1.0 }
println(sortedKeysAndValues) // [(A, [1, 2]), (D, [5, 6]), (Z, [3, 4])]

EDIT2: в настоящее время предпочитает синтаксис Swift, изменяющийся ежемесячно,

let sortedKeys = Array(dictionary.keys).sort(<) // ["A", "D", "Z"]

Глобальный sorted устарел.

125
ответ дан Moritz 18 August 2018 в 03:53
поделиться
  • 1
    Это дает вам массив ключей. В массиве отсутствуют значения. Думаю, вы могли бы искать значения из словаря. – StilesCrisis 24 December 2014 в 19:08
  • 2
    Ты прав. Я только что отредактировал сообщение, чтобы предоставить решение для получения массива пар (ключ, значение), отсортированных по ключам. Спасибо за комментарий. – Ivica M. 24 December 2014 в 19:27
  • 3
    @IvicaM. Здравствуйте! Я понял, как я могу сортировать словарь по ключам, но я не понимаю, как я могу сортировать массив элементов в словаре. Пожалуйста, помогите мне. Например, private var contacts: [(String, [User])] = [] – Alexander 14 August 2016 в 11:54
  • 4
    Swift 3 = Array (dictionary.keys) .sorted (by: & lt;) – miff 23 December 2016 в 12:48
  • 5
    С Swift 4 вы можете написать let sortedKeys = dictionary.keys.sorted() – Code Different 27 March 2018 в 12:47

«отсортировано» в iOS 9 & amp; xcode 7.3, swift 2.2 невозможно, измените «отсортированный» на «sort», например:

let dictionary = ["main course": 10.99, "dessert": 2.99, "salad": 5.99]
let sortedKeysAndValues = Array(dictionary).sort({ $0.0 < $1.0 })
print(sortedKeysAndValues)

//sortedKeysAndValues = ["desert": 2.99, "main course": 10.99, "salad": 5.99]
4
ответ дан AmyNguyen 18 August 2018 в 03:53
поделиться
  • 1
    Результат sortedKeysAndValues ​​не словарь, это массив! – Channel 30 November 2016 в 12:02
  • 2
    Результатом является Array of Tuples, а не Dictionary – Nilesh Pol 26 June 2018 в 09:47

Для Swift 3 следующий вид возвращает отсортированный словарь по клавишам:

let unsortedDictionary = ["4": "four", "2": "two", "1": "one", "3": "three"]

let sortedDictionary = unsortedDictionary.sorted(by: { $0.0.key < $0.1.key })

print(sortedDictionary)
// ["1": "one", "2": "two", "3": "three", "4": "four"]
4
ответ дан Arijan 18 August 2018 в 03:53
поделиться

Для Swift 4 для меня работало следующее:

let dicNumArray = ["q":[1,2,3,4,5],"a":[2,3,4,5,5],"s":[123,123,132,43,4],"t":[00,88,66,542,321]]

let sortedDic = dicNumArray.sorted { (aDic, bDic) -> Bool in
    return aDic.key < bDic.key
}
4
ответ дан Bryan P 18 August 2018 в 03:53
поделиться
  • 1
    Это не возвращает словарь, это вернет массив кортежей – Daniel Arantes Loverde 23 April 2018 в 21:19
  • 2
    Словари @DanielArantesLoverde по определению являются несортируемыми. Множество кортежей - лучшее, что вы можете сделать. – John Montgomery 1 May 2018 в 19:30
  • 3
    Я знаю это, но вопрос требует заказа, так что этот ответ неверен. Вы согласны? – Daniel Arantes Loverde 1 May 2018 в 20:53

Swift 2.0

Обновленная версия ответа Ivica M:

let wordDict = [
     "A" : [1, 2],
     "Z" : [3, 4],
     "D" : [5, 6]
]

let sortedDict = wordDict.sort { $0.0 < $1.0 }
print("\(sortedDict)") // 

Swift 3

wordDict.sorted(by: { $0.0 < $1.0 })

Примечание:

Некоторые из вас, похоже, удивлены тем, что результирующий массив не является словарем. Словари нельзя сортировать! Полученный тип данных представляет собой отсортированный массив, как и в ответе @ Ivica.

77
ответ дан Dan Beaulieu 18 August 2018 в 03:53
поделиться
  • 1
    это фактически возвращает массив из [(String, [Int])] не словарь – scord 12 February 2016 в 17:27
  • 2
    реализованные словари являются несортированными, поэтому в любом случае не имеет смысла создавать тип данных. Я закончил тем, что просто сохранил массив отсортированных ключей. – scord 12 February 2016 в 17:59
  • 3
    Спасибо за обновление – Roman Tsegelskyi 16 March 2016 в 19:30
  • 4
    Я получаю Binary operator > can not be compared to two Любые операнды. Downcasting не работает ни – Sean 2 August 2017 в 03:23

В быстром 4 вы можете написать умнее:

let d = [ 1 : "hello", 2 : "bye", -1 : "foo" ]
d = [Int : String](uniqueKeysWithValues: d.sorted{ $0.key < $1.key })
7
ответ дан Davide Gianessi 18 August 2018 в 03:53
поделиться
  • 1
    Спасибо за эти усилия, но прежде всего, "let & quot; не создает код, так что сначала он должен быть «var». Затем, после компиляции, этот код не работает, он не сортирует словарь, я получаю тот же результат до и после запуска этого кода. Может быть, я что-то упустил, но, пожалуйста, уточните больше или измените код. ======= var d = [1: "hello", 2: "bye", -1: "foo" ] print (d) - & gt; & gt; & gt; & gt; & gt; печатает [2: "bye", -1: "foo", 1: "hello"] d = [Int: String] (uniqueKeysWithValues: d.sorted {$ 0.key & lt; $ 1.key}) print ( d) - & gt; & gt; & gt; & gt; печатает [2: "bye", -1: "foo", 1: "hello"] – KarimIhab 26 July 2018 в 14:45

Я пробовал все вышеперечисленное, в двух словах все, что вам нужно, это

let sorted = dictionary.sorted { $0.key < $1.key }
let keysArraySorted = Array(sorted.map({ $0.key }))
let valuesArraySorted = Array(sorted.map({ $0.value }))

2
ответ дан Elsammak 18 August 2018 в 03:53
поделиться

Для Swift 3 для меня работало следующее, и синтаксис Swift 2 не работал:

// menu is a dictionary in this example

var menu = ["main course": 10.99, "dessert": 2.99, "salad": 5.99]

let sortedDict = menu.sorted(by: <)

// without "by:" it does not work in Swift 3
2
ответ дан Jonathan Leffler 18 August 2018 в 03:53
поделиться
  • 1
    Этот ответ довольно неполный. Что sortedDict? Что menu? Этот код также не является допустимым. – cale_b 12 August 2016 в 16:22
  • 2
    Теперь что-то более серьезное: словарь не имеет порядка . Что вы получаете с вашим кодом, это массив кортежей, а не отсортированный словарь - как уже сказано в некоторых ответах и ​​комментариях. – Moritz 15 August 2016 в 14:21
  • 3
    тема: сортировать словарь по ключам, я отвечаю на эту тему. И это специфическое замечание, касающееся только синтаксического изменения в Swift 3, оно не отрицает ничего из того, что было написано ранее. – Joeri 15 August 2016 в 15:54
  • 4
    «Этот ответ довольно неполный. Что такое сортировка? Что такое меню? Этот код также не является допустимым. - cale_b " Ответ был отредактирован, единственное, чего не хватало, это объявление для меню dictionaty. Я думал, что это ясно, это только изменение синтаксиса в Swift 3, как указано. Код работает в Swift 3. – Joeri 16 August 2016 в 05:02
  • 5
    Без "путем: & quot; работает в Swift 3.1 – Jonathan Cabrera 8 June 2017 в 22:45

Если вы хотите итерации по клавишам и значениям в сортированном порядке ключей, эта форма довольно кратка

let d = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

for (k,v) in Array(d).sorted({$0.0 < $1.0}) {
    println("\(k):\(v)")
}
25
ответ дан rks 18 August 2018 в 03:53
поделиться
  • 1
    Сортировка - это пользовательский метод или что? он показывает ошибку при реализации – rikky 10 March 2016 в 06:43
  • 2
    @rikkyG Swift 1: sort и sorted. Swift 2: sort стал sortInPlace, а sorted стал sort. – Moritz 16 March 2016 в 19:08

Swift 3 сортируется (по: & lt;)

let dictionary = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

let sortedKeys = Array(dictionary.keys).sorted(by:<) // ["A", "D", "Z"]
1
ответ дан Shadros 18 August 2018 в 03:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: