我目前在 Swift 中使用带有闭包的 map
属性从数组中提取线性因子并计算跨越一个 Octave 音程的音乐频率列表。
let tonic: Double = 261.626 // middle C
let factors = [ 1.0, 1.125, 1.25, 1.333, 1.5, 1.625, 1.875]
let frequencies = factors.map { $0 * tonic }
print(frequencies)
// [261.62599999999998, 294.32925, 327.03249999999997, 348.74745799999994, 392.43899999999996, 425.14224999999999, 490.54874999999993]
我想通过让闭包从字符串中提取两个整数并将它们相除以形成每个因子来实现这一点。该字符串来自 SCL tuning file可能看起来像这样:
// C D E F G A B
let ratios = [ "1/1", "9/8", "5/4", "4/3", "3/2", "27/16", "15/8"]
这可以做到吗?
解决方案
谢天谢地,是的,它可以。在三个 Swift 语句中,调谐比率表示为分数,因为在 Ptolemy 可以转换为精确频率之前。对接受的答案稍加修改就可以得出频率列表。这是代码
import UIKit
class ViewController: UIViewController {
// Diatonic scale
let ratios = [ "1/1", "9/8", "5/4", "4/3", "3/2", "27/16", "15/8"]
// Mohajira scale
// let ratios = [ "21/20", "9/8", "6/5", "49/40", "4/3", "7/5", "3/2", "8/5", "49/30", "9/5", "11/6", "2/1"]
override func viewDidLoad() {
super.viewDidLoad()
_ = Tuning(ratios: ratios)
}
}
调整类
import UIKit
class Tuning {
let tonic = 261.626 // frequency of middle C (in Hertz)
var ratios = [String]()
init(ratios: [String]) {
self.ratios = ratios
let frequencies = ratios.map { s -> Double in
let integers = s.characters.split(separator: "/").map(String.init).map({ Double($0) })
return (integers[0]!/integers[1]!) * tonic
}
print("// \(frequencies)")
}
}
这里是与全音阶的音符相对应的以赫兹为单位的频率列表
C D E F G A B
[261.626007, 294.329254, 327.032501, 348.834686, 392.439026, 441.493896, 490.548767]
它适用于其他音阶,其音高通常不会出现在黑白音符音乐键盘上 Mohajira scale created by Jacques Dudon
// D F G C'
let ratios = [ "21/20", "9/8", "6/5", "49/40", "4/3", "7/5", "3/2", "8/5", "49/30", "9/5", "11/6", "2/1"]
这里是产生的频率列表
// D F G C'
// [274.70729999999998, 294.32925, 313.95119999999997, 320.49185, 348.83466666666664, 366.27639999999997, 392.43899999999996, 418.60159999999996, 427.32246666666663, 470.92679999999996, 479.64766666666662, 523.25199999999995]
免责声明
目前闭包只处理有理尺度。完全符合Scala SCL format它还必须能够区分带分数的字符串和带小数点的字符串,并使用分来解释后者,即对数而不是线性因子。
最佳答案
let ratios = [ "1/1", "9/8", "5/4", "4/3", "3/2", "27/16", "15/8"]
let factors = ratios.map { s -> Float in
let integers = s.characters.split(separator: "/").map(String.init).map({ Float($0) })
return integers[0]!/integers[1]!
}
关于ios - 如何在 Swift 中创建闭包从字符串中提取两个整数以执行计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41312098/