Swift中的每隔一个奇数数组

bgtovc5b  于 2023-01-16  发布在  Swift
关注(0)|答案(3)|浏览(139)

我有一个名为“odd”的函数,它只返回一个包含奇数的数组,如下所示。

func odd(from start: Int, to end: Int) -> [Int] {
    let list = [Int](stride(from: start, to: end+1, by: 2))
    return list
}

我正在尝试做一个函数,它返回一个每隔一个奇数的数组,而不是每一个奇数。这个函数也应该是包含的。

func alternatingOdd(from start: Int, to end: Int) -> [Int] {
    var list = odd(from: start, to: end)
    // ... black magic trickery turns removes every other number from list... 
    return list
}

如下调用此函数:alternatingOdd(from: 1, to: 25)将返回一个[1, 5, 9, 13, 17, 21, 25]数组。
实质上,我是在问:我如何从数组中干净地删除所有其他元素?

EDIT:“odd”函数并不总是根据用户输入返回奇数数组。它只返回一个在一个范围内递增2的值数组。

我如何保护它并确保它总是只返回奇数?也就是说,数组中的每个元素都不能被2整除。

0vvn1miw

0vvn1miw1#

不是用stridefilter创建数组,而是用模运算符填充
odd函数保留奇数

func odd(from start: Int, to end: Int) -> [Int] {
    return (start...end).filter{$0 % 2 == 1}
}

或者使用更现代的API

func odd(from start: Int, to end: Int) -> [Int] {
    return (start...end).filter{$0.isMultiple(of: 2) == false}
}

alternatingOdd函数使用compactMap过滤索引

func alternatingOdd(from start: Int, to end: Int) -> [Int] {
    let list = odd(from: start, to: end)
    return list.indices.compactMap{$0 % 2 == 0 ? list[$0] : nil }
}
lsmepo6l

lsmepo6l2#

通过将每隔一个数组 * index * Map到对应的数组 * element:*,可以有效地剥离(任意)数组的每隔一个元素

func everySecond<T>(of array: [T]) -> [T] {
    return stride(from: array.startIndex, to: array.endIndex, by: 2).map { array[$0] }
}

示例:

print(everySecond(of: [1, 3, 2, 6, 4, 6])) // [1, 2, 4]
print(everySecond(of: ["H", "E", "L", "L", "O"])) // ["H", "L", "O"]

现在可以在函数中使用它

func alternatingOdd(from start: Int, to end: Int) -> [Int] {
    let odds = odd(from: start, to: end)
    return everySecond(of: odds)
}
iyr7buue

iyr7buue3#

你可以一次得到所有其他的奇数,而且效率更高,方法是:

func alternatingOdd(from start: Int, to end: Int) -> [Int] {
    guard start >= 0  else { return [] }

    let oddStart = (start % 2 == 0 ? 1 : 0) + start

    return Array(stride(from: oddStart, through: end, by: 4))
}

alternatingOdd(from: 1, to: 25)  //[1, 5, 9, 13, 17, 21, 25]

你甚至可以改变要丢弃的奇数个数:

func alternatingOdd(from start: Int, to end: Int, every step: Int) -> [Int] {
    guard start >= 0, step > 0  else { return [] }

    let oddStart = (start % 2 == 0 ? 1 : 0) + start

    return Array(stride(from: oddStart, through: end, by: 2 * step))
}

alternatingOdd(from: 1, to: 25, every: 2)  //[1, 5, 9, 13, 17, 21, 25]
alternatingOdd(from: 1, to: 25, every: 3)  //[1, 7, 13, 19, 25]

对于以负数开始的范围,可以只返回正奇数(如果有),方法如下:

func alternatingOdd(from start: Int, to end: Int, every step: Int) -> [Int] {
    guard step > 0  else { return [] }

    let oddStart = max((start % 2 == 0 ? 1 : 0) + start, 1)

    return Array(stride(from: oddStart, through: end, by: 2 * step))
}

alternatingOdd(from: -3, to: 10, every: 2)  //[1, 5, 9]
alternatingOdd(from: -3, to: 25, every: 4)  //[1, 9, 17, 25]

相关问题