Инициализируйте массив необязательных объектов с заданным размером n, где инициализатор объекта может завершиться ошибкой - PullRequest
0 голосов
/ 21 марта 2020

Длинное название, но я думаю, что это лучше всего отражает мою проблему.

Учитывая целое число n , я хотел бы инициализировать массив с не более n объектов.

Проблема в том, что объекты в массив не должен быть nil, однако конструктор для типа объекта может завершиться ошибкой (т. е. вернуть nil).

Есть два способа решения этой проблемы, и я думаю, что есть и другие - это Есть ли распространенное, передовое, хорошо известное или лучшее решение, чем два приведенных ниже?

struct MyClass {
  init?() {
    // ...
    if (/* cond */) { return nil }
  }
}

// ...

// 1. solution
struct A {
  let arr: [MyClass]
  let n = 6

  init?() {
    let arr = (0..<n).map { _ in MyClass() }
    guard arr.allSatisfy({ $0 != nil }) else { return nil }
    self.arr = arr as! [MyClass] // At this point we can safely force-cast
  }
}

// 2. solution
struct A {
  let arr: [MyClass]
  let n = 6

  init() {
    self.arr = (0..<n).map { _ in MyClass() }.reduce(into: []) { segments, segment in
      if let segment = segment {
        segments.append(segment)
      }
    }
  }
}

1 Ответ

5 голосов
/ 21 марта 2020

Вам нужно compactMap.

self.arr = (0..<n).compactMap { _ in MyClass() }

compactMap принимает замыкание, которое возвращает необязательное значение, и возвращает массив со всеми отфильтрованными значениями nils. Это должно быть именно то, что вы хотите, если я правильно понял.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...