在 Swift 中计算多维数组的维数

2023-11-30

假设我有一些函数想要使用多维数组(例如 Tensor 类)填充我的数据结构:

class Tensor {
   init<A>(array:A) { /* ... */ }
}

虽然我可以添加shape参数,我更喜欢自动计算数组本身的维度。如果您先验地知道尺寸,那么读出它就很简单:

let d1 = array.count
let d2 = array[0].count

然而,对于 N 维数组如何做到这一点还不太清楚。我在想可能有一种方法可以通过扩展 Array 类来做到这一点:

extension Int {
   func numberOfDims() -> Int {
      return 0
   }
}

extension Array {
   func numberOfDims() -> Int {
     return 1+Element.self.numberOfDims()
   }
}

不幸的是,这不会(理所当然地)编译,因为numberOfDims没有为大多数类型定义。但是,我没有看到任何限制的方法Element,因为数组的数组使事情变得复杂。

我希望其他人可能对如何解决这个问题有一些见解(或解释为什么这是不可能的)。


如果你想获取嵌套数组的深度(Swift 的标准库没有技术上为您提供多维数组,仅锯齿状数组)——然后,如图所示本次问答,您可以使用“虚拟协议”和类型转换。

protocol _Array {
    var nestingDepth: Int { get }
}

extension Array : _Array {
    var nestingDepth: Int {
        return 1 + ((first as? _Array)?.nestingDepth ?? 0)
    }
}

let a = [1, 2, 3]
print(a.nestingDepth) // 1

let b = [[1], [2, 3], [4]]
print(b.nestingDepth) // 2

let c = [[[1], [2]], [[3]], [[4], [5]]]
print(c.nestingDepth) // 3

(I believe this approach would've still worked when you had originally posted the question)

在 Swift 3 中,这也可以在没有虚拟协议的情况下实现,而是通过转换为[Any]。然而,正如链接的问答中所述,这是低效的,因为它需要遍历整个数组才能将每个元素装箱到存在容器中。

另请注意,此实现assumes您在同质嵌套数组上调用它。正如保罗指出的,它不会给出正确的答案[[[1], 2], 3].

如果需要考虑到这一点,您可以编写一个递归方法,该方法将迭代每个嵌套数组并返回嵌套的最小深度。

protocol _Array {
    func _nestingDepth(minimumDepth: Int?, currentDepth: Int) -> Int
}

extension Array : _Array {

    func _nestingDepth(minimumDepth: Int?, currentDepth: Int) -> Int {

        // for an empty array, the minimum depth is the current depth, as we know
        // that _nestingDepth is called where currentDepth <= minimumDepth.
        guard !isEmpty else { return currentDepth }

        var minimumDepth = minimumDepth

        for element in self {

            // if current depth has exceeded minimum depth, then return the minimum.
            // this allows for the short-circuiting of the function.
            if let minimumDepth = minimumDepth, currentDepth >= minimumDepth {
                return minimumDepth
            }

            // if element isn't an array, then return the current depth as the new minimum,
            // given that currentDepth < minimumDepth.
            guard let element = element as? _Array else { return currentDepth }

            // get the new minimum depth from the next nesting,
            // and incrementing the current depth.
            minimumDepth = element._nestingDepth(minimumDepth: minimumDepth,
                                                 currentDepth: currentDepth + 1)
        }

        // the force unwrap is safe, as we know array is non-empty, therefore minimumDepth 
        // has been assigned at least once.
        return minimumDepth!
    }

    var nestingDepth: Int {
        return _nestingDepth(minimumDepth: nil, currentDepth: 1)
    }
}

let a = [1, 2, 3]
print(a.nestingDepth) // 1

let b = [[1], [2], [3]]
print(b.nestingDepth) // 2

let c = [[[1], [2]], [[3]], [[5], [6]]]
print(c.nestingDepth) // 3

let d: [Any] = [ [[1], [2], [[3]] ], [[4]], [5] ]
print(d.nestingDepth) // 2 (the minimum depth is at element [5])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Swift 中计算多维数组的维数 的相关文章

随机推荐

  • 基于 REST API 令牌的身份验证

    我正在开发一个需要身份验证的 REST API 由于身份验证本身是通过 HTTP 上的外部 Web 服务进行的 因此我推断我们将分配令牌以避免重复调用身份验证服务 这让我想到了我的第一个问题 这真的比要求客户端在每个请求上使用 HTTP 基
  • 如何使用 iOS API 将 KML 文件 URL 加载到 Google 地图中?

    我将 Google 地图嵌入到 iPhone 地图的视图控制器中 我可以使用以下方法创建我的地图 GMSCameraPosition camera GMSCameraPosition cameraWithLatitude 39 93 lon
  • 如何在 MATLAB 中隐藏图形的线条,使其不会超出框架

    有什么方法可以隐藏溢出 以便线条不会像附图中那样从框架中突出 plot sin 0 0 1 10 LineWidth 10 您可以设置轴剪裁风格 to rectangle plot sin 0 0 1 10 LineWidth 10 set
  • PHP PDO 无法获取 OUT 参数值

    我刚刚开始将 PHP PDO 与 MySQL 存储过程一起使用 但我对如何从过程调用中获取 OUT 参数有疑问 我查看了许多类似的 stackoverflow 主题 但不幸的是我找不到解决我的问题的方法 详细信息如下 该过程采用 1 个输入
  • Python 字符串搜索,无论字符顺序如何

    我想创建一个应用程序 检查用户输入的单词是否包含来自单独文本文件的单词 单词 例如 输入 teeth 单独文件包含单词 eet 无论其序列如何 它都应该返回 True那些角色 我看了这个线程匹配正则表达式中任意顺序的所有字符这很酷 因为它使
  • 我可以使用 WPF 窗口中的 XamlReader.Load 或 InitializeFromXaml 来进行窗口定义吗?

    我想生成一些将包含在 WPF 应用程序中的库代码 根据情况 图书馆可能会弹出一个窗口 我可以在 XAML 中定义窗口 但我想将 XAML 视为模板 在运行时 在创建窗口以便可以显示它时 我想用运行时定义的值替换 Xaml 模板中的某些标记
  • C 中对 Gotoxy 的未定义引用

    我正在尝试用 C 语言编写一个程序 Windows 中的 code blocks 我添加了下面的头文件 它编译时没有错误 但是当运行代码时 它会抛出一个错误 未定义对 Gotoxy 的引用 找到完整的代码 只要我有 Gotoxy 语句 就会
  • 获取两个字符串中最长的

    有没有一种快速的方法来选择两个字符串中较长的一个 我想避免必须做的事情 if string1 gt string2 do a else if string2 gt string1 do b 字符串有一个方法length您可以使用 if st
  • 如何知道表单来自哪里?

    我想知道 PHP 中是否有一种方法可以告诉您表单提交的位置 而无需使用隐藏字段或类似的内容 用户只需要稍微篡改 html 即可 例如 我试图确定提交的表单是否实际上在我的网站上 或者该表单是否离线保存并以这种方式提交 如果隐藏字段包含 UI
  • 使用 PHP 关联数组查找笛卡尔积

    假设我有一个如下所示的数组 Array arm gt Array 0 gt A 1 gt B 2 gt C gender gt Array 0 gt Female 1 gt Male location gt Array 0 gt Vanco
  • 如何声明方法引用数组?

    我知道如何以这种方式声明其他事物的数组 例如字符串 String strings one two tree or String strings new String one two tree 但是当涉及到方法引用时 我不知道如何避免 创建列
  • 宽度左右边距 100%

    我有一个宽度设置为 100 的 div 我想将左右边距设置为 20px 由于某种原因 只有左侧被推了超过 20 像素 它忽视了权利 这是因为100 吗 去掉宽度 与所有块元素一样 div 会自动扩展以填充可用宽度 当您指定 100 的宽度时
  • 如何按所选列将 google 工作表导出为 CSV

    我有一个 Google 工作表想要导出为 CSV 文件 但工作表中有两列我不想导出 例如图中column 我不想导出列 N 和 P 这是我为导出编写的 Apps 脚本代码 function menu var ui SpreadsheetAp
  • 授权标头中不是有效的键=值对(缺少等号)

    在使用 Postman 的 API 时 我收到此错误 API详细信息 URL https account perf myglobal com v1 users 00uk0khprrME7gZOU0h7 credentials change
  • R 闪亮的 DT 包在选项卡之间构建链接

    在此处找到了在选项卡之间创建链接的解决方案R 闪亮构建选项卡之间的链接真的很好 但它不适用于 DT 包 对我来说 谁能告诉我 与没有 DT 包的解决方案相比 使用 DT 库的示例代码中我做错了什么 library shiny library
  • 如何使用python从公共谷歌表格中获取数据?

    我正在尝试获取以下 google 工作表的不同工作表中存在的 COVID 19 数据 g sheet 可供公众使用 URL 仅返回第一个工作表 我想抓取所有工作表 任何人都可以提供帮助吗 这是谷歌表格链接 https docs google
  • java.lang.ClassFormatError:类文件 javax/persistence/PersistenceException 中非本机或抽象的方法中缺少代码属性

    我是 JavaEE 新手 我使用 glassfish 服务器 3 1 在 NETBEANS 7 2 1 中创建了企业应用程序项目 当我尝试清理和构建时出现以下错误 An annotation processor threw an uncau
  • 尝试从其中检索 EC2 实例 ID 元数据时超时

    我正在启动一个 Windows 10 EC2 实例 并尝试使用以下命令从 CMD 检索它的实例 ID curl http 169 254 169 254 latest meta data instance id 这一直有效 直到昨天 但现在
  • Firebase Firestore .set 正在更新而不是创建(跳过规则)

    我正在使用 Android 客户端创建新文档 Map
  • 在 Swift 中计算多维数组的维数

    假设我有一些函数想要使用多维数组 例如 Tensor 类 填充我的数据结构 class Tensor init a array A 虽然我可以添加shape参数 我更喜欢自动计算数组本身的维度 如果您先验地知道尺寸 那么读出它就很简单 le