当前位置: 首页 > 面试题库 >

Swift 2D阵列通用扩展-访问第二维时出现问题

傅浩漫
2023-03-14
问题内容

我正在尝试将以下函数转换为2D数组的通用扩展。

func rotate(_ input: [[Int]]) -> [[Int]]
{
  let length = input[0].count
  var value = Array(repeating: [Int](), count: length)
  for index in 0 ..< length
  {
    value[index] = input.map { $0[index] }.reversed()
  }
  return value
}

我特别为如何指定约束以允许我访问第二维而感到困惑。这是一次失败的尝试:

extension Array where Element: Collection, Element.Iterator.Element: Collection
{
  private func rotate()
  {
    let count = self[0].count // Element.IndexDistance instead of Int

    // Expression type 'Array<Element>' is ambiguous without more context
    var returnValue = Array(repeating: Element, count: 11)
    for index in 0 ..< count // Element.IndexDistance instead of Int
    {
      returnValue[index] = self.map { $0[index] }.reversed()
    }
    return returnValue
  }
}

问题答案:

问题在于,编译器不知道您的扩展名是针对2D数组的,而只是知道它针对集合的数组。因此,关联的类型IndexDistanceIndex不一定Int

因此,解决的办法是限制您的扩展,使ElementIndexDistanceIndex
Int。这将使您形成范围0..<count,就像count现在将是IntIndexDistance)类型–并且将能够map(_:)Ints
下标html" target="_blank">元素(如下标所期望的Index)。

(一旦支持具体的同类型需求,这将是微不足道的,因为您可以简单地将约束Element为an Array,但这还不可能。)

您还应该注意,您的约束Element.Iterator.Element: Collection是不正确的,因为它将限制对3D集合数组的扩展(该数组的元素是一个集合,该集合的元素是一个集合)。

因此,当前方法的工作版本如下所示:

extension Array where Element: Collection, Element.Index == Int, Element.IndexDistance == Int {

    private func rotate() -> [[Element.Iterator.Element]] {

        typealias InnerElement = Element.Iterator.Element

        // in the case of an empty array, simply return an empty array
        if self.isEmpty { return [] } 
        let length = self[0].count

        var returnValue = [[InnerElement]](repeating: [InnerElement](), count: length)
        for index in 0..<length {
            returnValue[index] = self.map{ $0[index] }.reversed()
        }
        return returnValue
    }
}

就像@MartinR在下面指出的那样,可以通过使用nested大大简化它map(_:),从而消除了对a的需要,typealias因为我们不再需要创建“结果”数组:

private func rotate() -> [[Element.Iterator.Element]] {

    if self.isEmpty { return [] }
    let length = self[0].count

    return (0..<length).map { index in
        self.map { $0[index] }.reversed()
    }
}

尽管请注意,将扩展名限制为仅与Int索引一起使用并不是严格必要的(但是,由于您仅打算将其与2D数组一起使用,因此没有实际区别)。另一种选择是直接迭代内部集合的indices

为此,您只需要限制扩展名,以使内部集合Indices具有Element与集合相同类型Index的(对于ArrayIndices则为CountableRange<Int>):

extension Array where Element: Collection, Element.Indices.Iterator.Element == Element.Index {
    private func rotate() -> [[Element.Iterator.Element]] {

        if self.isEmpty { return [] }

        return self[0].indices.map { index in
            self.map { $0[index] }.reversed()
        }
    }
}


 类似资料:
  • 我正在开发一个chrome扩展,遇到了一个大问题。 奇怪的是,我可以访问iframe的html。因此,这段代码在chrome扩展中可以完美地工作: 我尝试将“all_frames”:true放入清单文件中,但没有成功:(

  • 我是编程新手,我有一个任务要求从一维数组创建二维数组。我想到了这一点(没有任何外部来源的帮助,因为这会剥夺学习经验)。它适用于我们教授的测试输入,我只是想知道这是一个丑陋/低效的解决方案。 测试输入:twoDArray([1,2,3,4,5],3)输出将是:[[1,2,3],[4,5]]

  • 我一直在使用字节好友来监控应用程序的行为,我想在执行特定方法之前检查其中一个应用程序类的数组字段是否已更新。我已经阅读了字节好友留档和堆栈溢出问题,并找到了一些有用的留档,了解如何使用拦截字段访问。 然而,因为我感兴趣的领域是一个数组,中的和事件似乎无关紧要。 是否可以使用ByteBuddy跟踪数组字段的更新?

  • 我想知道是否有一种方法可以用“简单的方法”来完成这件事,也许有人知道一个解决方案: 我正在使用javax.swing.text.html.HTMLDocument类,但由于某种原因,我需要的至少2个方法是非公开的,即便如此,我需要“重写”它们,以更改一些内容,但在某种程度上,我需要保留HTMLDocument类,因为我使用了大量的javax.swing.text.html包... 因此,我首先要做

  • 我已通过axios在阵列上发送数据(mySplitDays[splitDayIndex]=splitDay),但我有一个错误。。。 [Vue warn]:数据()中的错误:“引用错误:未定义mySplitDays” ReferenceError:未定义mySplitDays [Vue warn]:呈现错误:“TypeError:无法读取未定义的属性'length'” TypeError:无法读取P

  • 我可以通过本地J控制台访问Mbean,但无法从远程主机访问MBEANS。 我的配置: 远程进程:服务:jmx:远程处理-jmx://10.32.222.111:4447 我将用户添加到管理和应用领域 测试=2b1be81e1da41d4ea647bd82fc8c2bc9 但当我尝试连接它说:连接失败:重试 当我使用远程进程为:10.32.222.111:4447在服务器上提示警告: 16: 29: