如果两个数组包含相同的元素,无论这些元素出现的顺序如何,我如何检入Swift?

时间:2016-04-19 09:40:16

标签: arrays swift swift2

假设有两个阵列......

var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a"]

我希望这两个数组的比较结果为真,以及以下......

var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a", "d"]

......是假的。我怎样才能在Swift中实现这一目标?我试图将两个数组转换为集合,但由于某种原因,Set()不断删除数组包含的一些(通常是重复的)对象。

任何帮助都将不胜感激。

9 个答案:

答案 0 :(得分:64)

Swift 3,4

extension Array where Element: Comparable {
    func containsSameElements(as other: [Element]) -> Bool {
        return self.count == other.count && self.sorted() == other.sorted()
    }
}

// usage
let a: [Int] = [1, 2, 3, 3, 3]
let b: [Int] = [1, 3, 3, 3, 2]
let c: [Int] = [1, 2, 2, 3, 3, 3]

print(a.containsSameElements(as: b)) // true
print(a.containsSameElements(as: c)) // false

答案 1 :(得分:7)

你可以这样做:

  array1.sortInPlace()
  array2.sortInPlace()

  print(array1,array2)

  if array1 == array2 {
    print("equal")
  } else {
  print("not equal") 
  }

如果我们不想改变原始阵列,我们可以做到

 let sorted1 = array1.sort()
 let sorted2 = array2.sort()

  if sorted1 == sorted2 {
    print("equal")
  }else {
    print("not equal")
  }

答案 2 :(得分:3)

创建比较它们的函数:

func containSameElements(var firstArray firstArray: [String], var secondArray: [String]) -> Bool {
    if firstArray.count != secondArray.count {
        return false
    } else {
        firstArray.sortInPlace()
        secondArray.sortInPlace()
        return firstArray == secondArray
    }
}

然后:

var array1 = ["a", "a", "b"]
var array2 = ["a", "b", "a"]

var array3 = ["a", "b", "c"]
var array4 = ["b", "c", "a", "d"]

print(containSameElements(firstArray: array1, secondArray: array2)) //true
print(containSameElements(firstArray: array3, secondArray: array4)) //false
print(array1) //["a", "a", "b"]
print(array2) //["a", "b", "a"]
print(array3) //["a", "b", "c"]
print(array4) //["b", "c", "a", "d"]

答案 3 :(得分:2)

以下解决方案不要求元素为return books,而只需要[0]。它的效率远远低于排序答案,因此如果您的类型可以制作可比较的,请使用其中一种。

Comparable

答案 4 :(得分:2)

使用http://example.com/signup?token=1020a9e4-476a-4f74-b93a-b469d225dac0

Set

let array1 = ["a", "b", "c"] let array2 = ["b", "c", "a", "c"] let set1 = Set(array1) let set2 = Set(array2) if (set1.count == set2.count && set1 == set2) { //if you compare big sets it is recommended to compare the count of items in the sets beforehand //they are identical } 实现Set,因此任务是实现哈希函数以与Hashable一起使用

答案 5 :(得分:1)

Swift 4.1 / Xcode 9.4的解决方案:

extension Array where Element: Equatable {
    func containSameElements(_ array: [Element]) -> Bool {
        var selfCopy = self
        var secondArrayCopy = array
        while let currentItem = selfCopy.popLast() {
            if let indexOfCurrentItem = secondArrayCopy.index(of: currentItem) {
                secondArrayCopy.remove(at: indexOfCurrentItem)
            } else {
                return false
            }
        }
        return secondArrayCopy.isEmpty
    }
}

该解决方案的主要优点是它使用的内存比其他内存少(它总是只创建2个临时数组)。另外,Element不必Comparable,也不需要Equatable

答案 6 :(得分:1)

如果数组中的元素符合Hashable,则可以尝试使用包装袋(就像一个套袋,上面记录了每个物品的数量)。在这里,我将使用基于Dictionary的此数据结构的简化版本。此扩展名有助于从Hashable数组创建包:

extension Array where Element: Hashable {
    var asBag: [Element: Int] {
        return reduce(into: [:]) {
            $0.updateValue(($0[$1] ?? 0) + 1, forKey: $1)
        }
    }
}

现在,您需要从初始数组中生成2个袋子并进行比较。我将其包装在此扩展程序中:

extension Array where Element: Hashable {
    func containSameElements(_ array: [Element]) -> Bool {
        let selfAsBag = asBag
        let arrayAsBag = array.asBag
        return selfAsBag.count == arrayAsBag.count && selfAsBag.allSatisfy {
            arrayAsBag[$0.key] == $0.value
        }
    }
}

此解决方案已在Swift 4.2 / Xcode 10中进行了测试。如果您当前的Xcode版本低于10.0,则可以在Xcode9to10Preparation中找到allSatisfy中的函数ArraySlice。您可以使用CocoaPods安装该库。

答案 7 :(得分:1)

Swift 5.2解决方案

var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a"]

if array1.sorted() == array2.sorted() {
    print("array 1 & array 2 are same")
}

答案 8 :(得分:0)

我知道这个问题很老了,它也不想确定 array1 是否是 array2 的子集。但是,这适用于 Swift 5.3 和 Xcode 12.3:

user  nginx;
worker_processes  auto;

events {
  worker_connections  1024;
}

http {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  client_max_body_size 100m;
  sendfile       on;
  tcp_nopush     on;
  server_names_hash_bucket_size 128;
  keepalive_timeout  65;
  gzip  on;

  upstream backend {
    server backend:8000;
  }

  server {
    listen 80;
    charset utf-8;
    root /dist/;
    index index.html;

    # backend urls
    location ~ ^/(admin|api|accounts|media) {
      proxy_redirect off;
      proxy_pass http://backend;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
    }

    location /media {
      # autoindex on;
      alias /app/media;
    }

    location /static {
      # autoindex on;
      alias /app/static;
    }

    # frontend
    location / {
      try_files $uri $uri/ @rewrites;
    }

    location @rewrites {
      rewrite ^(.+)$ /index.html last;
    }
  }
}