我有以下数组:
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.做第三步
答案 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');