过滤和排序快速的字典数组

时间:2018-04-12 17:29:45

标签: ios swift filter swift4

我有以下数组:

let parent = [ ["Step":"S 3", "Desc":"Do third step" ],
               ["Step":"S 1", "Desc":"Do first step" ],
               ["Step":"S 2", "Desc":"Do second step" ],
                ["Step":"P 1", "Desc":"Some other thing" ] ]

如何在尽可能少的步骤中对数组进行过滤和排序(使用过滤器和排序函数),以便获得以下输出字符串或标签 -

1.第一步

2.第二步

3.做第三步

5 个答案:

答案 0 :(得分:4)

我建议过滤,排序,枚举,映射和加入:

let results = parent
    .filter { $0["Step"]?.first == "S" }
    .sorted { $0["Step"]!.compare($1["Step"]!, options: .numeric) == .orderedAscending }
    .enumerated()
    .map { (index, value) in "\(index + 1). \(value["Desc"]!)" }
    .joined(separator: "\n")

关键考虑因素是使用.numeric比较,以便“S 10”出现在“S 9”之后,而不是出现在“S 1”和“S 2”之间。如果要在字符串中嵌入数值,则不希望进行简单的字符串比较。

我也投入了枚举,因为如果删除某个项目,您可能希望确保列表中的数字不会因为Step字符串中的特定编码而跳过某个值。

无关,字典对于这样的事情来说是一个糟糕的模型。我建议使用自定义类型:

struct Task {
    enum TaskType {
        case step
        case process    // or whatever "P" is supposed to stand for
    }

    let sequence: Int
    let type: TaskType
    let taskDescription: String
}

let parent = [Task(sequence: 3, type: .step, taskDescription: "Do third step"),
              Task(sequence: 1, type: .step, taskDescription: "Do first step"),
              Task(sequence: 2, type: .step, taskDescription: "Do second step"),
              Task(sequence: 3, type: .process, taskDescription: "Some other thing")]

let results = parent
    .filter { $0.type == .step }
    .sorted { $0.sequence < $1.sequence }
    .map { "\($0.sequence). \($0.taskDescription)" }
    .joined(separator: "\n")

答案 1 :(得分:3)

描述答案:

首先,您需要过滤数组才能获得步骤;基于发布的parent数组,似乎有效步骤应该包含一个键作为“Step”和一个格式为“S#”的值,因此可以将其过滤为:

let filtered = parent.filter { (currentDict) -> Bool in
    // get the value for key "Step"
    guard let value = currentDict["Step"] else {
        return false
    }

    // check ifthe value matches the "S #"
    let trimmingBySpace = value.components(separatedBy: " ")
    if trimmingBySpace.count != 2 || trimmingBySpace[0] != "S" || Int(trimmingBySpace[1]) == nil {
        return false
    }

    return true
}

到目前为止会得到:

[["Step": "S 3", "Desc": "Do third step"],
 ["Step": "S 1", "Desc": "Do first step"],
 ["Step": "S 2", "Desc": "Do second step"]]

第二次,您可以使用“Step”键的值对filtered数组进行排序:

let sorted = filtered.sorted { $0["Step"]! < $1["Step"]! }

你应该得到:

[["Step": "S 1", "Desc": "Do first step"],
 ["Step": "S 2", "Desc": "Do second step"],
 ["Step": "S 3", "Desc": "Do third step"]]

最后,您将映射sorted数组以获取描述值:

let descriptions = sorted.map { $0["Desc"] ?? "" }

descriptions应该是:

["Do first step", "Do second step", "Do third step"]

一步到位:

let result = parent.filter { (currentDict) -> Bool in
    // get the value for key "Step"
    guard let value = currentDict["Step"] else {
        return false
    }

    // check ifthe value matches the "S #"
    let trimmingBySpace = value.components(separatedBy: " ")
    if trimmingBySpace.count != 2 || trimmingBySpace[0] != "S" || Int(trimmingBySpace[1]) == nil {
        return false
    }

    return true
    }.sorted {
    $0["Step"]! < $1["Step"]!
}.map {
    $0["Desc"] ?? ""
}

print(result) // ["Do first step", "Do second step", "Do third step"]

答案 2 :(得分:1)

我假设您的结构仍然如上所述使用强制展开。随意添加任何检查。

parent.filter { $0["Step"]!.contains("S") }.sorted { $0["Step"]! < $1["Step"]!
}.map { print($0["Desc"]!) }

答案 3 :(得分:1)

let sorted = parent.filter({ ($0["Step"]?.hasPrefix("S"))! }).sorted { $0["Step"]! < $1["Step"]!}
var prefix = 0
let strings = sorted.reduce("") { (partial, next) -> String in
   prefix += 1
   return partial + "\(prefix)." + next["Desc"]! + "\n"
}

答案 4 :(得分:1)

console.log('Subscribing the event!');
this.events.subscribe('app:sendUser', logged => {
    console.info(logged);
});

this.events.publish('app:getUser');