我可以像在 for 循环中从数组中索引项目一样从元组中检索项目吗?

Posted

技术标签:

【中文标题】我可以像在 for 循环中从数组中索引项目一样从元组中检索项目吗?【英文标题】:Can I retrieve an item from a tuple in the same way as indexing an item from an array in a for loop? 【发布时间】:2017-08-04 18:37:34 【问题描述】:

以下是我的自定义 UICollectionViewCell 类代码的一部分,我在for 循环中收到错误消息,指出函数定义中的元组类型没有下标成员。有谁知道是否有办法像检索数组一样检索元组的成员?谢谢!

    func initializeStuff(objectType: AnyObject, xOriginCgFloat: (CGFloat, CGFloat, CGFloat?), yOriginCgFloat: (CGFloat, CGFloat, CGFloat?), width: (CGFloat, CGFloat, CGFloat?), height: (CGFloat, CGFloat, CGFloat?))  

        if objectType === UIButton.self 
            if xOriginCgFloat.2 != nil || yOriginCgFloat.2 != nil || width.2 != nil || height.2 != nil 
                for index in 0..<3 
                    var button = UIButton(frame: CGRect.init(origin: CGPoint.init(x: xOriginCgFloat[index], y: yOriginCgFloat[index]), size: CGSize.init(width: width[index], height: height[index])))

                    buttonArray.append(button)
                
             else 
                fatalError("Each tuple for a button object must have exactly three values.")
            

【问题讨论】:

只是好奇,有什么理由你必须使用 CGFloats 的元组而不是 CGFloats 的数组? @RPatel99 是的。来自我昨天发布的***.com/questions/45494236/…。我猜它可以在编译期间检查错误,我猜这会降低应用程序崩溃的可能性。 Any way to iterate a tuple in swift?的可能重复 【参考方案1】:

查看this link 以获得此答案的灵感。首先将此函数添加到代码中可访问的位置:

func iterate<Tuple>(_ tuple:Tuple, body:(_ label:String?,_ value:Any)->Void) 
    for child in Mirror(reflecting: tuple).children 
        body(child.label, child.value)
    

然后使用您的代码的这个更新版本:

if objectType === UIButton.self 
        if xOriginCgFloat.2 != nil || yOriginCgFloat.2 != nil || width.2 != nil || height.2 != nil 
            var buttonOneData:[CGFloat] = [CGFloat]()
            var buttonTwoData:[CGFloat] = [CGFloat]()
            var buttonThreeData:[CGFloat] = [CGFloat]()
            var buttonsData:[[CGFloat]] = [buttonOneData,buttonTwoData,buttonThreeData]
            var tuples = [xOriginCgFloat,yOriginCgFloat,width,height]

            for tuple in tuples 
                iterate(tuple) 
                    var indexStr = $0! //index = .0,.1,.2, etc
                    indexStr.remove(at:indexStr.startIndex) //remove the . from .0,.1,.2,etc.
                    let index = Int(indexStr)
                    buttonsData[index].append(CGFloat($1 as! Int)) //$1 = the value of tuple.0, tuple.1, tuple.2, etc.
                
             

            for (index,buttonData) in buttonsData.enumerated() 
                var button = UIButton(frame: CGRect.init(origin: CGPoint.init(x: buttonData[index], y: buttonData[index]), size: CGSize.init(width: buttonData[index], height: buttonData[index])))
                buttonArray.append(button)
            

         else 
            fatalError("Each tuple for a button object must have exactly three values.")
        

它非常复杂,老实说我不是它的忠实粉丝,但如果你需要使用元组,那么这(可能)对你有用。我基本上使用了这个答案顶部列表中的迭代函数来遍历你的元组并将它们添加到数组中,这些数组将元组中的数据分隔成一个按钮数据数组,然后我制作了一个数组,这样你就可以遍历并制作实际的按钮。

【讨论】:

谢谢!随着我重复同一件事的次数,它确实看起来确实令人费解。也就是说,我从另一条评论中意识到,我的错误消息基本上只是为了让我调试我的代码,因为 func 在自定义类中。另外,你知道为什么func 在我尝试在同一个类中调用它时没有给我参数吗?它给了self.initializeStuff(self: customCollectionViewCell) 您是从单独的静态函数中调用initializeStuff 吗?我需要查看您的更多代码才能给您更具体的答案。 不,我是从函数外部调用它,但在同一个类中 如何发送消息?有点长 天哪,请不要这样做。【参考方案2】:

为什么不使用这样的函数:

func makeButtons(frames: [CGRect]) 
    for frame in frames 
        let button = UIButton(frame: frame)
        buttonArray.append(button)
    

【讨论】:

我有 UIButton,但我也有 UIView 和 UILabel,所以对于其他两个,我是否只需添加两个完全相同的功能? 实际上,您根本不清楚为什么您需要一个函数。重点是应该使用CGRect的数组,保证一致,而不是CGFloat的四个数组/元组,长度可能不一致。 谢谢!我制作函数是因为我不想手动初始化 3 个 UIButton、2 个 UIView 和 2 个 UILabel。我认为必须有一条捷径。

以上是关于我可以像在 for 循环中从数组中索引项目一样从元组中检索项目吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 的嵌套循环中从特定索引枚举字符串

可以像在 Python 中一样在 MATLAB 中进行并行遍历吗?

如何在 django 模板中从 for 循环中转义一行

在 numpy 中从具有索引的 2D 矩阵构建 3D 布尔矩阵

打字稿从元组/数组值派生联合类型

在 C# 中从锯齿状数组转换为双指针