如何在Swift中进行闭包从字符串中提取两个整数以执行计算 [英] How to make a closure in Swift extract two integers from a string to perform a calculation
问题描述
我目前正在使用 map
属性和Swift中的闭包来从数组中提取线性因子,并计算出跨越一个八度的音乐频率列表。
let补品:Double = 261.626 //中间C
let factor = [1.0,1.125,1.25,1.333, 1.5、1.625、1.875]
让频率= factor.map {$ 0 *补品}
打印(频率)
// // [261.62599999999998,294.32925,327.03249999999997, 348.74745799999994、392.43899999999996、425.14224999999999、490.54874999999993]
我想通过使闭包从中提取两个整数来实现此目的一个字符串并将它们除以形成每个因子。该字符串来自 SCL调整文件,可能看起来像这样:
// CDEFGAB
让比率= [ 1/1, 9/8, 5/4, 4/3, 3/2, 27/16, 15/8]
可以这样做吗?
解决方案
非常感谢,可以。在三个Swift语句中,自从托勒密之前可以覆盖到精确的频率以来,调整率就用分数表示。对已接受答案的稍作修改就可以得出频率列表。这是代码
import UIKit
类ViewController:UIViewController {
//整体音阶
让比率= [ 1/1, 9/8, 5/4, 4/3, 3/2, 27/16, 15/8]
//莫哈吉拉规模
//让比率= [ 21/20, 9/8, 6/5, 49/40 , 4/3, 7/5, 3/2, 8/5, 49/30, 9/5, 11/6, 2/1]
覆盖功能viewDidLoad(){
super.viewDidLoad()
_ =调整(比率:比率)
}
}
调优班
import UIKit
class Tuning {
let tonic = 261.626 //中间C的频率( inhertz)
var ratios = [String]()
init(ratios:[String]){
self.ratios =比率
令频率= ratios.map {s->将
中的双精度值让整数= s.characters.split(分隔符: /)。map(String.init).map({Double($ 0)})
return(integers [0]!/整数[1]!)*补品
}
print( // \(频率))
}
}
这是对应于全音阶音符的赫兹频率列表
CDEFGAB
[261.626007、294.329254、327.032501、348.834686、392.439026、441.493896、490.548767]
它适用于其他音阶,通常在黑白音符音乐键盘上找不到音高
雅克·杜顿(Jacques Dudon)创建的莫哈吉拉音阶
// DFG C'
的让手比率= [ 21/20, 9/8, 6/5, 49/40, 4/3, 7/5, 3/2 , 8/5, 49/30, 9/5, 11/6, 2/1]
这是产生的频率列表
// DFG C'
// [274.70729999999998,294.32925,313.95119999999997,320.49185,348.83466666666664,366.27639999999997,392.43899999999996,418.60159999999996,427.32246666666663,470.92679999999996,479.647666666666,523.25199999999 b
免责声明
当前,闭包仅处理合理规模。为了完全遵守 Scala SCL格式,它还必须能够区分字符串带有分数和带小数点的字符串,并使用美分来解释后者,即对数而不是线性因子。
解决方案
让比率= [ 1/1, 9/8, 5/4, 4/3, 3 / 2, 27/16, 15/8]
让因子= ratios.map {s->
中的浮点数让整数= s.characters.split(分隔符: /)。map(String.init).map({Float($ 0)})
返回整数[0]!/ integers [1]!
}
I am currently using map
property with a closure in Swift to extract linear factors from an array and calculate a list of musical frequencies spanning one 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]
I want to do this by making the closure extract two integers from a string and divide them to form each factor. The string comes from an SCL tuning file and might look something like this:
// C D E F G A B
let ratios = [ "1/1", "9/8", "5/4", "4/3", "3/2", "27/16", "15/8"]
Can this be done ?
SOLUTION
Thankfully, yes it can. In three Swift statements tuning ratios represented as fractions since before Ptolemy can be coverted into precise frequencies. A slight modification to the accepted answer makes it possible to derive the list of frequencies. Here is the code
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)
}
}
Tuning Class
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)")
}
}
And here is the list of frequencies in Hertz corresponding to notes of the diatonic scale
C D E F G A B
[261.626007, 294.329254, 327.032501, 348.834686, 392.439026, 441.493896, 490.548767]
It works for other scales with pitches not usually found on a black-and-white-note music keyboard
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"]
And here is a list of frequencies produced
// 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]
Disclaimer
Currently the closure only handles rational scales. To fully comply with Scala SCL format it must also be able to distinguish between strings with fractions and strings with a decimal point and interpret the latter using cents, i.e. logarithmic rather than linear factors.
Thank you KangKang Adrian and Atem
解决方案 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]!
}
这篇关于如何在Swift中进行闭包从字符串中提取两个整数以执行计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!