【问题标题】:How to remove an element(s) from several arrays and append again?如何从多个数组中删除一个元素并再次追加?
【发布时间】:2016-10-01 21:55:19
【问题描述】:

我有一个包含几个CGPoints 数组和数组数组的函数。我一直在“手动”从每个数组中删除点并将它们一一添加回来。这无疑是一种乏味且低效的方法。我正在寻找一种更有效的方法来处理数组的删除和附加点。这是我的代码:

func setSpritePositions ()   {
   groupA1 = [p1, p4, p6, p8]
   groupA2 = [p1, p3, p2, p5]

   groupB1 = [p1, p7, p2, p6]
   groupB2 = [p9, p4, p3, p2]
   groupB2 = [p2, p4, p5, p8]

   groupC1 = [p1, p7, p2, p7]
   groupC2 = [p9, p4, p3, p2]
   groupC3 = [p4, p5, p6, p7]
   groupC4 = [p5, p1, p3, p4]

   groupA = [groupA1, groupA2]
   groupB = [groupB1, groupB2, groupB3]
   groupC = [groupC1, groupC2, groupC3, groupC4]

   groups = [groupA, groupB, groupC]

} 

例如,我如何从包含它们的数组中删除点 p1p3p7,并记下这些数组并将位置附加回来。我将如何实现这一目标?正如我所说,我一直在做,这太麻烦了。

更新

我正在使用各种位置组来限制游戏中精灵的移动。有时我想删除某些位置,并能够知道稍后将它们附加回哪些数组。

【问题讨论】:

  • 迭代groups。对于每个数组,迭代其数组。对于这些数组中的每一个,查看它是否包含该点。如果是这样,删除然后附加它。
  • @rmaddy 你是指通过groups 访问所有其他数组吗?我正在使用所有其他数组,因此 groups 单独的更改不会在其他数组中受到影响,因为 swift 数组是值类型。我正在考虑使用NSArrays,但要操纵它们以获得某些结果将非常非常困难。
  • "并将位置追加到后面" 你真的是指在此处追加(例如,放在数组的末尾),还是真正的意思是“有时 p1 是活动的,有时不是。”我假设是后者,如果 p1 对一个组无效,那么它对所有组都无效。
  • @RobNapier 是的,如果有人说,p1 对一组无效,对所有人无效。实际上,使点处于活动或不活动状态将获得与删除和附加相同的结果。虽然似乎使点活跃和不活跃的方法可能是一个更好的解决方案。
  • @RobNapier 你能帮我看看下面的问题吗?我真的很感激任何帮助。 stackoverflow.com/questions/42120076/…

标签: arrays swift swift3


【解决方案1】:

答案是更好的类型。首先,如果您希望点具有共享状态,那么您需要一个引用类型,而不是值类型。您应该将您的积分提升到参考位置:

final class Location {
    let point: CGPoint
    var isActive: Bool = true
    init(_ point: CGPoint) { self.point = point }
}

现在您可以打开和关闭位置信息。

这是一个示例,说明如何将它与更好的类型一起使用。有很多方法可以设计它;这只是其中之一。然后,您可以将位置分组:

struct LocationSegment {
    let locations: [Location]
    var activePoints: [CGPoint] { 
        return locations.filter{ $0.isActive }.map{ $0.point }.uniqueValues()
    }
}

这使得获取活动点列表变得容易。这假设扩展名如下:

extension Array where Element: Equatable {
    // Warning: This is O(n^2). You can't do better than that without making CGPoint Hashable
    // (which is easy, but left as a separate problem.)
    func uniqueValues() -> [Element] {
        var result: [Element] = []
        for element in self {
            if !result.contains(element) {
                result.append(element)
            }
        }
        return result
    }
}

现在我们有了细分,我们可以将它们分组:

struct LocationGroup {
    let segments: [LocationSegment]
    var activePoints: [CGPoint] { return segments.flatMap { $0.activePoints }.uniqueValues() }
}

如果我们有一组组:

let groups = [groupA, groupB, groupC]

我们可以得到所有的活跃点:

groups.flatMap { $0.activePoints }

同样,这只是一种方法。您可能希望groups 成为比[LocationGroup] 更强大的类型,或者您可能希望将LocationGroup 重新设计为递归枚举,以便您可以完全使用值类型来构建它(尽管我认为这个特殊问题需要一个底部的参考类型)。关键是要构建能表达你的意思的类型,而不是试图强制数组成为你想要的一切。

【讨论】:

  • 哇!这不仅解决了这个问题,还解决了我遇到的六个其他问题。非常感谢,真的很感激。
猜你喜欢
  • 2022-03-19
  • 2012-06-19
  • 2010-10-04
  • 2021-03-22
  • 1970-01-01
  • 2020-10-21
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多