Можете ли вы написать замыкание forEach () в строке .append () в Swift 5? Получаем ошибку, пока - PullRequest
0 голосов
/ 03 апреля 2020

Я новичок в Swift и пытаюсь поэкспериментировать с языком, чтобы ознакомиться со всеми интересными функциями. В настоящее время я пытаюсь написать закрытие forEach для добавления другой строки в зависимости от значения элемента в forEach. Переменная lightStates является списком [Bool]. Я ищу, чтобы statusStr была строкой "1" и "0" в зависимости от того, является ли элемент b в закрытии forEach истинным или ложным,

Я получаю ошибку "Declared closure result 'String' is incompatible with contextual type 'Void'" на линии String in ... внутри замыкания.

   var statusStr : String = ""
   statusStr.append(lightStates.forEach{ (b:Bool) -> String in return b ? "1":"0"})
   return "Lights: \(statusStr) \n"

В идеале я хотел бы знать, разрешено ли / возможно ли то, что я делаю. Но также я открыт для предложений о том, как получить желаемую функциональность (печать строки "1" и "0" на основе массива [Bool] с)

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Вариант 1 ( простейший ):

lightStates.map { $0 ? "1" : "0" } .joined()

Вариант 2 ( многоразового использования ):

Сохранение битов в целочисленном типе ( UInt подходит до 64), а затем превратить его в строку.

public extension Sequence {
  /// The first element of the sequence.
  /// - Note: `nil` if the sequence is empty.
  var first: Element? {
    var iterator = makeIterator()
    return iterator.next()
  }

  /// - Returns: `nil` If the sequence has no elements, instead of an "initial result".
  func reduce(
    _ getNextPartialResult: (Element, Element) throws -> Element
  ) rethrows -> Element? {
    guard let first = first
    else { return nil }

    return try dropFirst().reduce(first, getNextPartialResult)
  }

  /// Accumulates transformed elements.
  /// - Returns: `nil`  if the sequence has no elements.
  func reduce<Result>(
    _ transform: (Element) throws -> Result,
    _ getNextPartialResult: (Result, Result) throws -> Result
  ) rethrows -> Result? {
    try lazy.map(transform).reduce(getNextPartialResult)
  }
}
public extension BinaryInteger {
  /// Store a pattern of `1`s and `0`s.
  /// - Parameter bitPattern: `true` becomes `1`; `false` becomes `0`.
  /// - Returns: nil if bitPattern has no elements.
  init?<BitPattern: Sequence>(bitPattern: BitPattern)
  where BitPattern.Element == Bool {
    guard let integer: Self = (
      bitPattern.reduce( { $0 ? 1 : 0 } ) { $0 << 1 | $1 }
    ) else { return nil }

    self = integer
  }
}
if let lightStatesInteger = Int(bitPattern: lightStates) {
  _ = String(lightStatesInteger, radix: 0b10)
}
0 голосов
/ 04 апреля 2020

Да, вы делаете в первую очередь неправильно. Foreach ничего не возвращает, а функция добавления требует чего-то добавить.

Вы можете использовать карту здесь вместо foreach. что-то вроде этого

statusStr.append(contentsOf: array.map { $0.description == "true" ? "1" : "2" })

я знаю, что это не оптимизированное или лучшее решение, но я просто пытаюсь очистить логи c здесь.

...