我正在尝试删除swift中具有多个相同值的相同精确顺序的某些数组元素 即
假设现在我有3个数组
array1 = [a,b,c,d,d,c,d]
array2 = [1,2,3,4,4,3,4]
array3 = [aa,bb,cc,dd,dd,cc,dd]
问题是:我需要从数组中删除共有3个重复值的元素
这意味着,我需要摆脱索引的元素:[4],[5],[6]来自数组1,2和3。
PS。 3个数组必须是分开的数组,并且不能重新排列它的顺序,因为它们有一些彼此相关的关键信息
任何建议都将不胜感激。
答案 0 :(得分:3)
var array1 = ["a","b","c","d","d","c","d"]
var array2 = [1,2,3,4,4,3,4]
var array3 = ["aa","bb","cc","dd","dd","cc","dd"]
var set: Set<Int> = [] // you can use a set to check the duplicated elements
for index in array2.indices.reversed() { // reversed is necessary to remove your elements
if !set.insert(array2[index]).inserted {
array1.remove(at: index)
array2.remove(at: index)
array3.remove(at: index)
}
}
array1 // ["a", "b", "c", "d"]
array2 // [1, 2, 3, 4]
array3 // ["aa", "bb", "cc", "dd"]
答案 1 :(得分:1)
元组是Equatable
(假设它们的元素是Equatable
)直到arity 6,我们可以利用这里将三个数组压缩成3元组序列,识别重复3 -tuple元素,并从原始的三个数组中删除与这些元组关联的索引。但是,元组不是Hashable
,所以我们不会使用3元组,而是可以回退到存储三个值的实用程序Hashable
类型(3元组确实匿名输入)。
实用程序类型:
struct ZippedElement: Hashable {
let a: String
let b: Int
let c: String
init(_ a: String, _ b: Int, _ c: String) {
self.a = a
self.b = b
self.c = c
}
// Use a very simple common hashValue calculation, simply
// falling back on the hashValue of the Int member.
var hashValue: Int { return b.hashValue }
static func ==(lhs: ZippedElement, rhs: ZippedElement) -> Bool {
return lhs.a == rhs.a && lhs.b == rhs.b && lhs.c == rhs.c
}
}
这允许我们对array1
到array3
执行过滤/变异操作,如下所示:
var seen = Set<ZippedElement>()
zip(zip(array1, array2), array3)
.map { ZippedElement($0.0, $0.1, $1) }
.enumerated().filter { !seen.insert($1).inserted }
.map { $0.offset }.reversed()
.forEach {
array1.remove(at: $0)
array2.remove(at: $0)
array3.remove(at: $0)
}
结果,在每个数组中删除了最后三个元素:
print(array1) // ["a", "b", "c", "d"]
print(array2) // [1, 2, 3, 4]
print(array3) // ["aa", "bb", "cc", "dd"]
您的示例数据设置不会对此处的不同解决方案构成许多挑战,但是,@ dasblinkenlight提出了一个很好的问题:
如果我用
"dd"
替换array3
的{{1}},会改变所需的结果吗?
在这种情况下,我相信我们大多数人都认为应该保留所有原始数组中的第7个元素,因为&#34; vertical&#34;对于第7个元素(/列),所有三个数组上的zip组合都是唯一的。
对这样的修改示例应用与上述相同的方法:
"dx"
你的问题的另一个评论由@SteveKuo提出,说明我们大多数人的想法(对于所有问题都有一些有趣的算法练习),例如这个问题(索引跟踪单独的数组......) ):
似乎更合适的数据结构是创建array1 / 2/3属性的struct / class / tuple。
我相信这是你应该带着的核心答案,所以即使你明确说明了
... ps。 3个数组必须是分开的数组
您可能需要一个自定义类型的单个数组。
答案 2 :(得分:0)
您可以将数组放入一个集合(其本身不包含重复项),然后将其传回数组。
e.g。
var array2: [Int] = [1,2,3,4,4,3,4]
let set2 = Set<Int>(array2)
array2 = Array(set2).sorted()
如果您还需要针对其他数组设置逻辑,则可以执行set2.subtract(otherSequence)
之类的操作。
答案 3 :(得分:0)
其他解决方案涵盖了一种工作方法,但所有这些都在O(n ^ 2)时间内完成,因为迭代遍历数组并重复调用remove(at:)
,这本身就是一个O(n)操作。
假设所有3个阵列在相同的位置都有重复,这里是一个功能性的O(n)方法,它使用交换,然后在结束时只修改一次数组。不确定性能有多重要,但这应该在更大的数据集上显着更快。
var array1 = ["a","b","c","d","d","c","d"]
var array2 = [1,2,3,4,4,3,4]
var array3 = ["aa","bb","cc","dd","dd","cc","dd"]
var set: Set<Int> = []
var lastIndex = 0
for index in array2.indices
{
if set.insert(array2[index]).inserted
{
array1.swapAt(index, lastIndex)
array2.swapAt(index, lastIndex)
array3.swapAt(index, lastIndex)
lastIndex += 1
}
}
let numToRemove = array1.count - lastIndex
array1.removeLast(numToRemove)
array2.removeLast(numToRemove)
array3.removeLast(numToRemove)