简体   繁体   English

快速比较两个数组的内容

[英]Compare the content of two arrays in swift

I have an array that I have to cut, on the first 3, 7 or 30 entries. 我必须在前3、7或30个条目上剪切一个数组。

Then I have an ArraySlice which I want to pack into an array. 然后我有一个ArraySlice,我想打包成一个数组。

Now if I want to compare the new array I created from the ArraySlice with another array (if both have the same content) I always get false as the result. 现在,如果我想将我从ArraySlice创建的新数组与另一个数组(如果两者都具有相同的内容)进行比较,我总是得到false。

I believe it is due to the newly created Array from the ArraySlice. 我相信这是由于ArraySlice中新创建的Array引起的。

What can I do so that the result is not always false. 我应该怎么做才能使结果不总是错误的。 the content is the same, have checked it with print (...) 内容相同,已通过打印(...)进行了检查

extension Date {
    static func compareLastDays (compareArray: [Date]) -> Bool{

        var compareArray2: [Date] = []
        var createDateArray: [Date] = []

        var days = compareArray.count

        if days >= 30 {
            days = 30
            let arraySlice =  compareArray.prefix(days)
            compareArray2 = Array(arraySlice)
        }
        else if days >= 7{
            days = 7
            let arraySlice = compareArray.prefix(days)
            compareArray2 = Array(arraySlice)
        }
        else {
            days = 3
            let arraySlice = compareArray.prefix(days)
            compareArray2 = Array(arraySlice)
        }

        let startDate = Date.init()
        var endDate = Calendar.current.date(byAdding: .day, value: -days, to: startDate)!

        print("startDate", startDate)
        print("endDate", endDate)


        while startDate > endDate{
            createDateArray.insert(endDate, at: 0)
            guard let newDate = Calendar.current.date(byAdding: .day, value: 1, to: endDate) else {
                break
            }
            print("extension new Date", newDate)
            endDate = newDate
        }
        print(compareArray2, "extension compareArray")
        print(createDateArray, "extension createDateArray")


        if createDateArray == compareArray2 {
            print("Compare ARRAY true", createDateArray, compareArray2)
            return true
        }
        else {
            print("Compare ARRAY false", createDateArray, compareArray2)
            return false
        }

    }
}

print statements: 打印报表:

    startDate 2019-07-28 19:00:22 +0000 
    endDate 2019-07-21 19:00:22 +0000 
    extension new Date 2019-07-22 19:00:22 +0000 
    extension new Date 2019-07-23 19:00:22 +0000
    extension new Date 2019-07-24 19:00:22 +0000 
    extension new Date 2019-07-25 19:00:22 +0000 
    extension new Date 2019-07-26 19:00:22 +0000 
    extension new Date 2019-07-27 19:00:22 +0000 
    extension new Date 2019-07-28 19:00:22 +0000 

[2019-07-27 19:00:22 +0000, 2019-07-26 19:00:22 +0000, 2019-07-25 19:00:22 +0000, 2019-07-24 19:00:22 +0000, 2019-07-23 19:00:22 +0000, 2019-07-22 19:00:22 +0000, 2019-07-21 19:00:22 +0000] extension compareArray 
[2019-07-27 19:00:22 +0000, 2019-07-26 19:00:22 +0000, 2019-07-25 19:00:22 +0000, 2019-07-24 19:00:22 +0000, 2019-07-23 19:00:22 +0000, 2019-07-22 19:00:22 +0000, 2019-07-21 19:00:22 +0000] extension createDateArray 
Compare ARRAY false [2019-07-27 19:00:22 +0000, 2019-07-26 19:00:22 +0000, 2019-07-25 19:00:22 +0000, 2019-07-24 19:00:22 +0000, 2019-07-23 19:00:22 +0000, 2019-07-22 19:00:22 +0000, 2019-07-21 19:00:22 +0000] [2019-07-27 19:00:22 +0000, 2019-07-26 19:00:22 +0000, 2019-07-25 19:00:22 +0000, 2019-07-24 19:00:22 +0000, 2019-07-23 19:00:22 +0000, 2019-07-22 19:00:22 +0000, 2019-07-21 19:00:22 +0000]

One way to solve this is to extract some of the date components for the dates and then compare the components. 解决此问题的一种方法是为日期提取一些日期成分,然后进行比较。

The below code will fail when comparing the dates directly but succeed when comparing the components which goes from year down to seconds 下面的代码在直接比较日期时将失败,但是在比较从年份到秒的组件时将成功

let now = Date()
let now2 = Date()
print(now == now2 ) // -> false

let components1 = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute, .second], from: now)
let components2 = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute, .second], from: now2)
print(components1 == components2) // -> true

To make the code clearer the set of components can be made into a constant 为了使代码更清晰,可以将组件集设为常量

let compareSet:Set<Calendar.Component> = [.year, .month, .day, .hour, .minute, .second]

A similar solution to this could be to use a DateFormatter and compare the strings. 与此类似的解决方案是使用DateFormatter并比较字符串。 Both offers the possibility to easily set the precision used when comparing dates 两者都可以轻松设置比较日期时使用的精度

Here is a way to do with a DateFormatter but in this example the comparison is only done down to minutes 这是使用DateFormatter的一种方法,但是在此示例中,比较仅需进行几分钟即可完成

let df = DateFormatter()
df.dateStyle = .full
df.timeStyle = .short
print(df.string(from: now) == df.string(from: now2))

Of course for either solution the arrays can't be compared directly and instead they need to be looped over and each component needs to be compared individually to the component in the other array 当然,对于任何一种解决方案,都无法直接比较数组,而是需要对其进行循环,并且需要将每个组件分别与另一个数组中的组件进行比较。

Below is an example using the date formatter solution 以下是使用日期格式化程序解决方案的示例

guard compareArray2.count == createDateArray.count else { return false}
for i in 0..<compareArray2.count {
    if df.string(from: compareArray2[i]) != df.string(from: createDateArray[i]) {
        return false
    }
}
return true

since the code is tricky and you said it doesn't work which it should, i found you this work around: 由于代码很棘手,并且您说它不应该这样做,所以我发现您可以解决此问题:

extension Array where Element: Hashable {
    func isSame(from other: [Element]) -> Bool {
        let thisSet = Set(self)
        let otherSet = Set(other)
        let arr = Array(thisSet.symmetricDifference(otherSet))

        if arr.count == 0{
            return true
        }else{
            return false
        }
    }
}

let date1 = Date()
let date2 = Date()
let date3 = Date()
let arr1 = [date1,date2,date3]
let arr2 = [date1,date2]

arr1.isSame(from: arr2)

if the 2 arrays are the same, it return true, else false. 如果两个数组相同,则返回true,否则返回false。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM