我长期以来一直在努力想出一个优雅的解决方案来解决这个问题。这是一个占星应用程序项目,我想要实现的是一个定位系统。
struct Position {
var sign: Int
var degrees: Int
var minutes: Int
}
在此系统中,符号只能是 1…12。因此,例如,如果将 13 传递给符号变量,则它应该从 1 开始。 度数应实现相同的逻辑,并限制在 0…29 之间。因此,传递给 Degrees 变量的 30 应转换为 1。 分钟限制为 0…59。同样的逻辑。
我正在努力实现它,并让它看起来合乎逻辑且简约。我是否需要创建自定义类型来存储此类值?应用程序应使用的实际格式是,例如:1 23’ 45"。
编辑
如果我将 1 分钟添加到 12 符号 29 度 59 分钟,它应该转换为 0 0 0。就像日期一样。
您应该注意,符号、度数和分钟的表示在技术上只是人类对单个数字的表示。您使用
Date
的示例是一个很好的例子,因为这应该让您意识到 Date
在内部由单个 Double
表示,我们仅在需要时将其转换为组件(并且转换对于日期来说非常复杂)。
因此,我建议的第一件事是用一个数字来表示所有三个值(实际上是分钟的总数)。
那么每次计算都可以只是这个数字的修改。
我将使用的概念非常常见,实际上与位置数字相同(例如数字
1234
= ((((1 * 10) + 2) * 10) + 3) * 10 + 4
)。您可能还通过从秒数计算小时和分钟来了解这个概念。
struct Position: CustomStringConvertible {
// considering sign to be 0...11
static let signCount = 12
// degrees are 0...29
static let degreeCount = 30
// minute are 0...29
static let minuteCount = 60
// the total number of possible values, value is 0...(maxValue - 1)
static let maxValue = signCount * degreeCount * minuteCount
// if value is outside the permitted range, normalize it
private static func normalizeValue(_ value: Int) -> Int {
if value >= maxValue {
// simple modulo operation
return value % maxValue
}
if value < 0 {
// make negative values positive and within the correct range
return maxValue + value % maxValue
}
return value
}
private var value: Int
init(value: Int) {
self.value = Self.normalizeValue(value)
}
init(sign: Int, degrees: Int, minutes: Int) {
// calculate position value from components
let value = ((sign * Self.degreeCount) + degrees) * Self.minuteCount + minutes
self.value = Self.normalizeValue(value)
}
var sign: Int {
return value / (Self.degreeCount * Self.minuteCount)
}
var degrees: Int {
return (value / Self.minuteCount) % Self.degreeCount
}
var minutes: Int {
return value % Self.minuteCount
}
func adding(_ position: Position) -> Position {
return Position(value: value + position.value)
}
func adding(sign: Int, degrees: Int, minutes: Int) -> Position {
let position = Position(sign: sign, degrees: degrees, minutes: minutes)
return adding(position)
}
var description: String {
return "Sign \(sign + 1), \(degrees)° \(minutes)′"
}
}
测试:
let position = Position(sign: 23, degrees: 29, minutes: 59)
print(position) // Sign 12, 29° 59′
print(position.adding(sign: 0, degrees: 0, minutes: 2)) // Sign 1, 0° 1′
print(position.adding(sign: -13, degrees: 0, minutes: 0)) // Sign 11, 29° 59′
请注意,我仅在格式化时才将
+1
添加到符号中。但是,如果您想将符号存储为 1..12
,则可以在将 1
加载/存储到位置值时简单地更新代码以添加/减去 sign
。
这是一个简单的计算属性,可以为您完成工作。在我的示例中,我是在
0 based index
(换句话说 upper limit - 1
)上完成的。如果您想删除该功能,请更改每个 0 to a 1
并将每个 max:
增加 +1
class Position {
var sign: Int {
get{ return getConstrainedValue(value: self.sign, max: 12) }
set{}
}
var degrees: Int {
get{ return getConstrainedValue(value: self.degrees, max: 29) }
set{}
}
var minutes: Int {
get{ return getConstrainedValue(value: self.minutes, max: 59) }
set{}
}
func getConstrainedValue(value: Int, max limit: Int) -> Int {
// If value is greater than limit, return first value, 0.
// Otherwise, if value is less than 0, return the limit.
// Otherwise return the value.
return value > limit ? 1 : value < 1 ? limit : value
}
init(sign: Int, degrees: Int, minutes: Int) {
self.sign = sign
self.degrees = degrees
self.minutes = minutes
}
}
let test = Position(sign: 12, degrees: -1, minutes: 58)
print("sign: \(test.sign) degrees: \(test.degrees) minutes: \(test.minutes)")
如果您雇用任何开发人员来开发像 astrotalks 这样的应用程序,您可能需要大约 2 到 5,000 美元。但如果你购买源代码并通过查看文档自行开发,则需要花费 50 美元左右。您可以从这里购买该源代码。 https://www.codester.com/items/44883/astrotalks-astrology-consultation-script如果您也无法自己开发,那么任何开发人员都可以收取大约 100-200 美元的费用来将此源代码开发为应用程序。欲知更多详情,您也可以whatsapp我们+9779814581248。谢谢你