3

I'm accessing a C language struct in my Swift project that stores data as a tuple and I want to iterate over it.

let tuple = (1, 2, 3, 4, 5)

AFAIK, I have two options. The first is to mirror the tuple so that I can map its reflection into an array:

let tupleMirror = Mirror(reflecting: tuple)
let tupleArray = tupleMirror.children.map({ $0.value }) as! [Int]

And the second option is to translate it into an array using manual memory management with something like an unsafe buffer pointer. From all that I've read, it's usually suggested to avoid the manual-memory route if possible and Mirror certainly appears to do that. Is mirroring a safe/reliable way to convert a tuple to an array? Or is there a better approach to translating the tuple into an array or even iterating over the tuple itself?

8
  • Is your tuple always of arbitrary length? Why do you want to keep it as a tuple? Why don't use array from the beginning? Commented Mar 17, 2020 at 15:25
  • @MaximKosov The length is constant. And I don't want to keep it as a tuple. In my example, I've translated it to an array. And modifying the C code is not an option (third-party dependency). Commented Mar 17, 2020 at 15:27
  • 1
    So, if the length is constant, say 5, can you just write a regular function? Like let arr = [tuple.0, tuple.1, ...]? Commented Mar 17, 2020 at 15:29
  • 1
    Looks like on the apple forums they suggest to use UsafeBufferPointer. forums.developer.apple.com/thread/72120 Commented Mar 17, 2020 at 15:32
  • 1
    I don't think tuple could be not constant size, to be honest Commented Mar 17, 2020 at 15:33

1 Answer 1

5

Mirror is fiiiiiiiiiiiiine.

extension Array {
  init?<Subject>(mirrorChildValuesOf subject: Subject) {
    guard let array = Mirror(reflecting: subject).children.map(\.value) as? Self
    else { return nil }

    self = array
  }
}
  XCTAssertEqual(
    Array( mirrorChildValuesOf: (1, 2, 3, 4, 5) ),
    [1, 2, 3, 4, 5]
  )

  XCTAssertNil(
    [Int]( mirrorChildValuesOf: (1, 2, "3", 4, 5) )
  )
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.