Подсчет уникальных идентификаторов во вложенном массиве с использованием Swift - PullRequest
0 голосов
/ 27 октября 2018

У меня есть следующий вложенный массив, и я пытаюсь подсчитать, сколько элементов с уникальным ids существует.В массиве под счетчиком должно быть 2.

Массив имеет тип List<SolData> он исходит из области

class SolData: Object {
    @objc dynamic var uid = "";
    @objc dynamic var id = "";
}

extension SolData: ListDiffable {
    func diffIdentifier() -> NSObjectProtocol {
        return uid as NSObjectProtocol
    }

    func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
        if let object = object as? SolData {
            return uid == object.uid
        }
        return false
    }
}

Печать массива.

 (
    [0] SolData {
        uid = sdasd;
        id = jmX3;
    },
    [1] SolData {
        uid = gfd;
        id = jmX3;
    },
    [2] SolData {
        uid = hgfd;
        id = jmX3;
    },
    [3] SolData {
        uid = terw;
        id = jmX3;
    },
    [4] SolData {
        uid = fgg;
        id = GFdda;
    }
)

Я попытался использовать map следующим образом

var count = 0;
var prevId = "";

let uniqueSols = diff.sol.map{ (s) -> Int in
  if s.id != prevId {
    count = count + 1;
    prevId = s.id;
  }
  return count;
}

print(uniqueSols);

Но я получаю следующую ошибку.

SWIFT RUNTIME BUG: невозможно разобрать тип поля '_transform'.имя искаженного типа: 'q_7ElementSTQzc' 2018-10-27 14: 26: 08.793528 + 0300 App [23634: 611928] Ошибка SWIFT RUNTIME: не удалось разобрать тип поля '_transform'.имя искаженного типа: 'q_7ElementSTQzc', _transform: ())

1 Ответ

0 голосов
/ 27 октября 2018

Чтобы воспроизвести ваш код, я собираюсь смоделировать класс SolData и добавить инициализатор, чтобы упростить создание экземпляров:

class SolData {
    var uid: String = ""
    var id: String = ""

    init(uid: String, id: String) {
        self.uid = uid
        self.id  = id
    }
}

Давайте создадим несколько экземпляров:

let zero  = SolData(uid: "sdasd", id: "jmX3")
let one   = SolData(uid: "gfd",   id: "jmX3")
let two   = SolData(uid: "hgfd",  id: "jmX3")
let three = SolData(uid: "terw",  id: "jmX3")
let four  = SolData(uid: "fgg",   id: "GFdda")

И сгруппировать их в массив:

let array = [zero, one, two, three, four]

Чтобы получить только экземпляры с уникальными идентификаторами, давайте использовать reduce(into:):

let uniqueIds = array.reduce(into: Set<String>(), { $0.insert($1.id)})

Свойство count uniqueIds - это число уникальных идентификаторов в array:

let uniqueIdsCount = uniqueIds.count  //2

Если вам нужен массив экземпляров с уникальными идентификаторами, используйте следующее:

let instancesWithUniqueIds = array.reduce(into: [SolData]()) { accumulator, element in
    if accumulator.allSatisfy({ $0.id != element.id}) {
        accumulator.append(element)
    }
}

accumulator.allSatisfy({ $0.id != element.id}) возможно заменить на accumulator.contains(element) и сделать SolData соответствующим Hashable.

...