1

我有一个函数可以在某些条件下生成一个数字

func randomWithCondition() -> Int {
  ...
  return n
}

稍后我将使用这个函数在另一个函数中构建一个长度为 N 的数组

func a() -> [Int] {
  var arr = [Int]()
  for _ in 0..<length {
    arr.append(randomWithCondition())
  }
  return arr
}

我想把这些写在一行中,我能想到的最好的事情是

return (0..<N).map { _ in randomWithCondition() }

我必须添加_ in,因为我没有使用$0,否则将无法编译。

问题:有没有不写的地方_ in?任何其他格式都可以,只要它是 return 语句中的一行。

4

2 回答 2

1

您需要自己定义一些额外的功能。

例如,一个const函数(名称受 Haskell 启发,但您可以withParameter改为调用它):

func const<T, U>(_ f: @escaping () -> U) -> ((T) -> U) {
    { _ in f() }
}

然后你可以这样做:

return (0..<N).map(const(randomWithCondition))

我认为您还应该将其包装在一个generate函数中:

func generate<T>(_ count: Int, generator: @escaping () -> T) -> [T] {
    (0..<count).map(const(generator))
}

请注意,您还可以使用sequence而不是mapping 范围来创建惰性无限序列。

于 2020-12-23T11:56:07.020 回答
1

map将每个元素从其类型转换为其他类型,以便转换需要闭包中的参数。Range但为方便起见,您可以通过对and进行扩展来省略此参数ClosedRange

extension Range where Bound: Strideable, Bound.Stride: SignedInteger {
    public func map<T>(_ transform: () -> T)  -> [T] {
        map { _ in transform() }
    }
}

extension ClosedRange where Bound: Strideable, Bound.Stride: SignedInteger {
    public func map<T>(_ transform: () -> T)  -> [T] {
        map { _ in transform() }
    }
}

let range = (0..<10).map { arc4random() }
print(range)
// Outputs: [676946806, 482060909, 1553829324, 1660236508, 606395000, 268649066, 1438948568, 1995527535, 918698113, 505678702]

let closedRange = (0...9).map { arc4random() }
print(closedRange)
// Outputs: [20467139, 198204705, 1585520963, 2022302907, 2518334206, 3304761403, 3782378335, 3830286797, 2200585433, 2387902936]
于 2020-12-23T14:34:54.877 回答