如何更好地构建此代码?

时间:2018-01-08 22:53:59

标签: swift

我真的想知道你在课堂上为这样的任务做了多少结构,因为我现在很震惊我的答案对于这家公司的采访来说还不够题。他们确实要求我约会,看看它是在今天和之前的5天之间。所以,让我知道还有什么需要在这里完成。

有问题的日期传递给一个函数。该功能需要今天的日期,然后您在今天的日期前5天比较相关日期。如果有问题的日期是从5天前提升的,那么如果日期是从今天的日期开始下降,则该函数返回true。所以有人让我知道我在哪里出错。

func compareDate(thisDate:Date,aheadOfDate:Date, beforeThisDate:Date) -> Bool{
    if( thisDate < aheadOfDate){
        return false
    }
    if(thisDate > beforeThisDate){
        return false
    }
    return true
}

func daysFromToday(days:Int) -> Date{

    let calendar = Calendar.current
    let newDate = calendar.date(byAdding: .day, value: days, to:  Date.init())
    return newDate!
}

let todaysDate = Date.init()
let fiveDaysAgo = daysFromToday(days:-5)

print(compareDate(thisDate: daysFromToday(days: 1), aheadOfDate: fiveDaysAgo, beforeThisDate: todaysDate))

4 个答案:

答案 0 :(得分:1)

从今天的日期减去给定的日期并查看天数的差异是否介于0和5之间会更简单。另外,IDK如果关心,但compareDate函数可以改为单行布尔解释。

答案 1 :(得分:1)

第一个功能

我会重组为Date上的扩展程序:

extension Date {
    func isBetween(_ first: Date, and second: Date) -> Bool {
        return first < self && self < second
    }
}

然后我会用范围表达式a < b && b < c替换此a...c ~= b模式,这会创建一个日期范围,并检查其中是否有self

extension Date {
    func isBetween(_ first: Date, and second: Date) -> Bool {
        return first...second ~= self
    }
}

第二功能

我还会重新构建Date上的扩展程序,我会内联calendarnewDate因为它们会增加视觉混乱,而不会提供任何新信息。我还会用Date.init()替换Date()

extension Date {
    func offset(days: Int) -> Date {
        return Calendar.current.date(byAdding: .day, value: days, to:  self)
    }
}

用法

在最后的片段中,我将使用这些函数:

let now = Date()
let fiveDaysAgo = now.offset(days: -5)

print(now.offset(days: +1).isBetween(fiveDaysAgo, and: now))

答案 2 :(得分:1)

我认为目前的答案缺失的是,如果你想比较日期,你需要花时间超出等式(这与不关心时间不一样)。所以对于那个面试问题,你真正说的是'我正在检查的日期&gt; = 5天前和明天开始之前的那天的开始'。毕竟,如果你今天晚上10点检查它,那么5天前的早上9点仍然可以,但如果你在所有检查中都包括时间,那就不行了。

因此,在进行任何检查之前,您需要计算5天前和明天的开始时间,这样做是这样的:

extension Date {
    func isBetween(date: Date, andDaysAgo daysAgo: Int) -> Bool {
        let cal = Calendar.current
        var start = cal.startOfDay(for: date)
        let inYesterday = cal.date(byAdding: .day, value: -daysAgo, to: date)!
        start = cal.startOfDay(for: inYesterday)

        var end = cal.startOfDay(for: date)
        let inTomorrow = cal.date(byAdding: .day, value: 1, to: date)!
        end = cal.startOfDay(for: inTomorrow)

        return start..<end ~= self
    }
}

(这比您想象的要复杂得多,因为您必须考虑不同的时区和格式以及夏令时等事项。)

然后,根据您的使用方式,您可以执行以下操作:

var checkDate = Date(timeIntervalSinceNow: 3600 * 24 * 0)
print (checkDate.isBetween(date: Date(), andDaysAgo: 5) // prints true
checkDate = Date(timeIntervalSinceNow: 3600 * 24 * -5)
print (checkDate.isBetween(date: Date(), andDaysAgo: 5) // prints true
checkDate = Date(timeIntervalSinceNow: 3600 * 24 * 1)
print (checkDate.isBetween(date: Date(), andDaysAgo: 5) // prints false
checkDate = Date(timeIntervalSinceNow: 3600 * 24 * -6)
print (checkDate.isBetween(date: Date(), andDaysAgo: 5) // prints flase

你会这样称呼:

func isBetweenAlt(date: Date, andDaysAgo daysAgo: Int) -> Bool {
    let cal = Calendar.current
    let startCheck = cal.date(bySettingHour: 12, minute: 0, second: 0, of: cal.date(byAdding: .day, value: -daysAgo, to: date)!)!
    let endCheck = cal.date(bySettingHour: 12, minute: 0, second: 0, of: date)!
    let checkDate = cal.date(bySettingHour: 12, minute: 0, second: 0, of: self)!

    return startCheck...endCheck ~= checkDate
}

(这些只是快速入侵的例子)

修改

正如我所指出的那样(非常正确)如果你比较日期并且不关心时间,那么你可以使用正午作为你的参考点(基本上它总是固定的,不受夏令时变化之类的影响)。所以这是一种方法:

func isBetweenAlt2(date: Date, andDaysAgo daysAgo: Int) -> Bool {
    let cal = Calendar.current
    let startCheck = cal.date(byAdding: .day, value: -(daysAgo + 1), to: date)! // You have to offset by one day as the test will be > not >=
    let endCheck = cal.date(byAdding: .day, value: 1, to: date)! // You have to offset by one day as the test will be < not <=

    return cal.compare(startCheck, to: self, toGranularity: .day) == .orderedAscending && cal.compare(endCheck, to: self, toGranularity: .day) == .orderedDescending
}

func isBetweenAlt3(date: Date, andDaysAgo daysAgo: Int) -> Bool {
    let cal = Calendar.current
    let startCheck = cal.ordinality(of: .day, in: .era, for: cal.date(byAdding: .day, value: -daysAgo, to: date)!)!
    let endCheck = cal.ordinality(of: .day, in: .era, for: date)!
    let check = cal.ordinality(of: .day, in: .era, for: self)!

    return startCheck...endCheck ~= check
}

同样本着学习的精神,还有其他几种方法可以做到:

{{1}}

所有人都做同样的工作(我认为)。

修改

回顾原始问题和采访中的这类测试。通常有一个问题的多种解决方案可能都同样有效,面试问题的想法不一定是得到他们认为正确的答案,而是表明你已经考虑过影响问题的问题。特别是对于初级开发人员角色而言,答案在当时是完整的并不重要,但更重要的是,该人理解问题,所涉及的挑战以及如何解决问题。

答案 3 :(得分:0)

我让你的代码更短,更“快速”了

char = socket.recv(1)