根据不同 NSOrderedSet 中指定的顺序重新排序 NSOrderedSet
Reorder NSOrdered Set based on the order specified in a different NSOrderedSet
所以,我有两个有序集,它们的结构是这样的,一个有序集基本上有一个字典列表,另一个有序集有与字典中某个值对应的字符串。让我用一个例子来说明:
OrderedSetA = [["key1": "test", "key2": "A"], ["key1": "test2", "key2": "B"], ["key1": "test3", "key2":"C"], ["key1": "test4", "key2": "E"]]
OrderedSetB = ["B","G","H", "A", "E", "D", "C", "F", "J", "K"]
所以,现在我基本上想根据为与 OrderedSet B 中的 key2
对应的字符串指定的顺序重新排列 OrderedSetA 中的元素,同时忽略 B 中不在 A 中的任何值。所以例如,在这种情况下,我要寻找的是:
OrderedSetC = [["key1": "test2", "key2": "B"], ["key1": "test1", "key2": "A"], ["key1": "test4", "key2":"E"], ["key1": "test3", "key2": "C"]]
这是我到目前为止尝试过的方法:
let orderedSetC = orderedSetA.filter {OrderedSetB.contains(([=14=] as AnyObject).key2)}
这里发生的是 returns 同样的事情,我想我是根据 OrderedSetB 中的任何东西进行过滤,它不在 OrderedSetA 中,但是没有 sorting/reordering 发生.
什么是最合适和最有效的 Swift 5 处理方法?
谢谢!
您可以使用带谓词的过滤器:
let osA: NSOrderedSet = ["A", "B", "C", "D", "E", "F"]
let osB: NSOrderedSet = ["B", "G", "H", "A", "C", "D", "E", "F", "J", "K"]
let osC = osB.filtered(using: .init(block: { (element, _) in
osA.contains(element as Any)
}))
您还可以创建一个有序集 B 的 NSMutableOrderedSet 并与 A 相交:
var osC = osB.mutableCopy() as! NSMutableOrderedSet
osC.intersect(osA)
print(Array(osC)) // ["B", "A", "C", "D", "E", "F"]
另一种选择是实施您自己的本机 Swift OrderedSet
,正如我在此 answer 中发布的那样。将 OrderedSet 添加到您的项目后,您可以简单地获得有序集 A intersection ordered set B:
let osA: OrderedSet = ["A", "B", "C", "D", "E", "F"]
let osB: OrderedSet = ["B", "G", "H", "A", "C", "D", "E", "F", "J", "K"]
let osC = osB.intersection(osA) // ["B", "A", "C", "D", "E", "F"]
edit/update:
不确定为什么需要 NSOrderedSet
词典。 IMO 你应该构建你的数据。无论如何,如果你真的想这样做,你可以使用 reduce(into:)
:
let osA: NSOrderedSet = [["key1": "test", "key2": "A"], ["key1": "test2", "key2": "B"], ["key1": "test3", "key2":"C"], ["key1": "test4", "key2": "E"]]
let osB: NSOrderedSet = ["B","G","H", "A", "E", "D", "C", "F", "J", "K"]
let osC: NSMutableOrderedSet = osB.reduce(into: .init(), { (os, any) in
guard let object = osA.first(where: { element in
(element as? [String: String] ?? [:])?.values.contains(any as? String ?? "") == true
}) else { return }
os.add(object)
})
所以,我有两个有序集,它们的结构是这样的,一个有序集基本上有一个字典列表,另一个有序集有与字典中某个值对应的字符串。让我用一个例子来说明:
OrderedSetA = [["key1": "test", "key2": "A"], ["key1": "test2", "key2": "B"], ["key1": "test3", "key2":"C"], ["key1": "test4", "key2": "E"]]
OrderedSetB = ["B","G","H", "A", "E", "D", "C", "F", "J", "K"]
所以,现在我基本上想根据为与 OrderedSet B 中的 key2
对应的字符串指定的顺序重新排列 OrderedSetA 中的元素,同时忽略 B 中不在 A 中的任何值。所以例如,在这种情况下,我要寻找的是:
OrderedSetC = [["key1": "test2", "key2": "B"], ["key1": "test1", "key2": "A"], ["key1": "test4", "key2":"E"], ["key1": "test3", "key2": "C"]]
这是我到目前为止尝试过的方法:
let orderedSetC = orderedSetA.filter {OrderedSetB.contains(([=14=] as AnyObject).key2)}
这里发生的是 returns 同样的事情,我想我是根据 OrderedSetB 中的任何东西进行过滤,它不在 OrderedSetA 中,但是没有 sorting/reordering 发生.
什么是最合适和最有效的 Swift 5 处理方法?
谢谢!
您可以使用带谓词的过滤器:
let osA: NSOrderedSet = ["A", "B", "C", "D", "E", "F"]
let osB: NSOrderedSet = ["B", "G", "H", "A", "C", "D", "E", "F", "J", "K"]
let osC = osB.filtered(using: .init(block: { (element, _) in
osA.contains(element as Any)
}))
您还可以创建一个有序集 B 的 NSMutableOrderedSet 并与 A 相交:
var osC = osB.mutableCopy() as! NSMutableOrderedSet
osC.intersect(osA)
print(Array(osC)) // ["B", "A", "C", "D", "E", "F"]
另一种选择是实施您自己的本机 Swift OrderedSet
,正如我在此 answer 中发布的那样。将 OrderedSet 添加到您的项目后,您可以简单地获得有序集 A intersection ordered set B:
let osA: OrderedSet = ["A", "B", "C", "D", "E", "F"]
let osB: OrderedSet = ["B", "G", "H", "A", "C", "D", "E", "F", "J", "K"]
let osC = osB.intersection(osA) // ["B", "A", "C", "D", "E", "F"]
edit/update:
不确定为什么需要 NSOrderedSet
词典。 IMO 你应该构建你的数据。无论如何,如果你真的想这样做,你可以使用 reduce(into:)
:
let osA: NSOrderedSet = [["key1": "test", "key2": "A"], ["key1": "test2", "key2": "B"], ["key1": "test3", "key2":"C"], ["key1": "test4", "key2": "E"]]
let osB: NSOrderedSet = ["B","G","H", "A", "E", "D", "C", "F", "J", "K"]
let osC: NSMutableOrderedSet = osB.reduce(into: .init(), { (os, any) in
guard let object = osA.first(where: { element in
(element as? [String: String] ?? [:])?.values.contains(any as? String ?? "") == true
}) else { return }
os.add(object)
})