【问题标题】:How to remove only adjacent duplicates in an array of integers in Swift?如何在 Swift 中仅删除整数数组中的相邻重复项?
【发布时间】:2020-04-10 10:42:42
【问题描述】:

我的实现:

extension Array where Element:Equatable {
    func removeDuplicates() -> [Element] {
        var result = [Element]()

        for value in self {
            if result.contains(value) == false {
                let r = result.append(value)       
            }
        }
        return result
    }
}
let arrayOfInts = [1, 2, 2, 3, 3, 3, 1].reverse()
for element in arrayOfInts.removeDuplicates(){
    print(element)
}

我想在删除相邻整数后对数组执行操作。

【问题讨论】:

  • 嗨。我在这里没有得到你需要的东西,你的问题很不清楚。我认为let arrayOfUniqueInts = arrayOfInt.removeDuplicates() 是您要处理的数组,但我不确定您对相邻的东西需要什么...您能帮我们帮忙吗?
  • 是的,你理解得很好。我首先想接收我的数组并删除其中相邻的重复项。然后我想对其进行变异,并仍然以变异顺序返回包含已删除重复项的数组。在这里,我提到它是颠倒的。
  • 为什么要反转数组?这与删除相邻重复问题有什么关系?我对此有点困惑。

标签: arrays swift duplicates


【解决方案1】:

您的扩展是在数组上定义的,并且 reversed 将反向视图返回到数组中,因此您需要衰减为实际数组。请参阅下面的解决方案。

extension Array where Element:Equatable {
  func removeConsecutiveDuplicates() -> [Element] {
    var previousElement: Element? = nil
    return reduce(into: []) { total, element in
      defer {
        previousElement = element
      }
      guard previousElement != element else {
        return
      }
      total.append(element)
    }
  }
}
let arrayOfInts = Array([1, 2, 2, 3, 3, 3, 1].reversed())
for element in arrayOfInts.removeConsecutiveDuplicates() {
    print(element)
}

编辑:我应该添加以删除连续元素,这足以像我的示例中那样记住最后一个元素。如果您想要所有重复项,请使用Set<Element> 而不是您的示例中的[Element],因为包含在集合上是 O(C),但在数组上是 O(n)。

【讨论】:

  • 这是一个很好的解决方案。但是一旦我删除了arrayOfInts = Array([1, 2, 2, 3, 3, 3, 1].reversed())中的Array(),它给了我与“”“错误相同的错误:'ReversedCollection类型的值' 没有成员 'removeConsecutiveDuplicates'"""
  • @DDD 因为一旦你反转了Array,它就不再是一个数组,它变成了一个单独的类型,叫做ReversedCollection。如果您想将此扩展应用于ReversedCollection 类型以及数组,则需要创建一个不限于数组的扩展,并且包括Reversed CollectionArray 类型或将ReversedCollection 转换为Array
  • 如果我必须始终传入数组,我是否必须编写一个没有“扩展”的方法?这个想法是传入一个数组并在需要时对其进行变异,而无需调用它。谢谢
【解决方案2】:

这可以通过将当前数组的元素添加到新数组来简单地解决,但仅在当前元素不等于最后一个元素时附加当前元素以解决重复相邻问题。 试试这个解决方案。

extension Array where Element:Equatable {
func removeDuplicates()->[Element]{
    guard !self.isEmpty else { return [] }
    var noDuplicates = [Element]()

    for (index, element) in self.enumerated(){
        if index > 0{

            if element != noDuplicates.last{

                noDuplicates.append(element)
                   }
        }
        else{
            noDuplicates.append(element)
        }


    }

    return noDuplicates
}
}

编辑:此外,如果您在反转数组后在 ReversedCollection 上使用此扩展时遇到问题,那是因为 Swift 将其识别为与 Array 类型不同。一旦你反转了Array,它就不再是一个数组,它变成了一个单独的类型,称为ReversedCollection。如果您想将此扩展应用于ReversedCollection 类型以及数组,则需要创建一个不限于数组的扩展,并且包括Reversed CollectionArray 类型或将ReversedCollection 转换为Array

extension Collection where Element:Equatable {

或者

let arrayOfInts = Array([1, 2, 2, 3, 3, 3, 1].reversed())
for element in arrayOfInts.removeDuplicates(){
    print(element)
}

【讨论】:

  • 谢谢。有没有其他方法可以解决这个问题,而不必每次传入数组时都调用数组?
  • 我不确定你的意思,你能详细说明一下吗?
  • 如果您的问题与此相关,则集合的扩展根本不需要您调用数组
  • 您对 Collections 的扩展是什么意思?有没有一种方法可以调用两个扩展并调用一个方法来执行它们?目的是在调用数组时不定义或传入关键字“Array”。
猜你喜欢
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 2023-01-02
  • 2012-12-04
  • 1970-01-01
相关资源
最近更新 更多