Улучшить сравнение двух массивов Swift - PullRequest
0 голосов
/ 28 августа 2018

У меня есть приложение, в котором пользователь может щелкнуть по другому профилю пользователя, и приложение будет сравнивать телефонные контакты обоих пользователей и искать общие контакты. Это работает, но это занимает много времени, поэтому мне было интересно, есть ли способ ускорить это хотя бы немного.

**** Примечание. Я новичок в разработке для iOS и до сих пор не очень хорошо знаком с синтаксисом Swift и iOS в целом, поэтому любая помощь будет очень признательна

Вот мой простой Contact класс:

class Contact: Hashable, Equatable {
  var hashValue: Int { get { return phoneNumber!.hashValue } }
  var name: String?
  var phoneNumber: String?
  var thumbnail: Data?
  var filled: Bool?

  init() {
  }

  init(name: String?, phoneNumber: String?, thumbnail: Data?) {
    self.name = name
    self.phoneNumber = phoneNumber
    self.thumbnail = thumbnail
}
static func ==(lhs: Contact, rhs: Contact) -> Bool {
    return lhs.phoneNumber == rhs.phoneNumber
  }
}

Я реализовал, как вы можете видеть, Hashable и Equatable, которые я использую для сравнения контактов по номеру телефона и удаления дубликатов. Вот код, где я выполняю основную операцию сравнения. Массив contacts содержит телефонные контакты пользователя, а otherContacts - массив телефонных контактов другого пользователя.

                for result in self.contacts {
                if self.otherContacts.contains(result){
                    self.commonContacts.append(result)
                }
            }
            self.removedDuplicates = Array(Set(self.commonContacts))
            if self.removedDuplicates.count == 1 {
                self.commonFriends.text = "\(1) common friend"
            }
            else {
                self.commonFriends.text = "\(self.removedDuplicates.count) common friends"
            }

Спасибо.

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Есть ли причина, по которой контакты это массив? Я бы использовал Set<Contact>, так как вы можете легко выполнять операции над множествами.

Чтобы получить общие элементы каждого набора, предполагая, что ваша реализация хэш-кода верна, просто используйте Set.intersection(_:)

0 голосов
/ 28 августа 2018

Для массивов, содержит O(n) производительность. Поэтому проверка всех элементов из одного массива в сравнении с другим массивом имеет производительность O(n^2) (n-квадрат), что плохо.

Скопируйте телефонные номера из одного массива в набор и используйте функцию Set contains(_:), которая очень близка к постоянной производительности, что дает вам общую производительность O(n), что значительно, намного лучше.

0 голосов
/ 28 августа 2018

Вы можете попробовать объединиться с Dictionary, это может дать вам повышение.

var commonContacts = Dictionary(uniqueKeysWithValues: contacts.lazy.map{ return ($0.phoneNumber!, $0) })
    .merge(otherContacts.lazy.map{ ($0.phoneNumber!, $0) }, uniquingKeysWith: {
        contact1, _ in contact1 // Can do merging of duplicates here.
    })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...