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

Например, с учетом хэш-набора h = [1,2,3,4,5] цель состоит в том, чтобы подсчитать количество уникальных элементов i, чтобы h.contains(i+1).

Я мог записать быстрый код, используя reduce() как

h.reduce(0,{h.contains($1+1) ? $0 + 1 : $0})

Но что если h является массивом, содержащим дубликаты вместо хэш-набора?Сначала мне нужно преобразовать его в хэш-набор, а затем использовать приведенное выше выражение:

Set(h).reduce(0,{Set(h).contains($1+1) ? $0 + 1 : $0})

Но, таким образом, мы рассчитали Set(h).count + 1 раз Set (h), как указано в @ carpsen90, есть ли способнаписать код как

Set(h).reduce(0,{self.contains($1+1) ? $0 + 1 : $0})

без использования временной переменной для хранения Set(h)?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Проблема в том, что ваш массив может содержать дубликаты, и для фильтрации дубликатов проще всего преобразовать его в набор.И правильный способ сделать это - сохранить набор в новой переменной, следовательно, это неизбежно.

Хотя вы все равно можете использовать метод Reduce без преобразования вашего массива в набор, подобный этому:

var tempH = [Int]()
let c = h.reduce(0) { (result, item) in
    if (!tempH.contains(item)) {
        tempH.append(item)
        return h.contains(item+1) ? (result + 1) : result
    }
    else {return result}
}

Но, как вы можете заметить в приведенном выше коде, мы должны использовать временный массив для отслеживания наших дубликатов.Следовательно, дополнительная переменная кажется здесь неизбежной.Хотя в вышеприведенном коде наборы не используются.

0 голосов
/ 27 февраля 2019

Каждый раз, когда вы звоните Set(h), вычисляется новый набор, поэтому в вашем примере Set(h).reduce(0,{Set(h).contains($1+1) ? $0 + 1 : $0}), Set(h) будет вычислено h.count + 1 раз.Переменная let set = Set (h) - вот путь:

let set = Set(h)
let result = set.reduce(0) {set.contains($1+1) ? $0 + 1 : $0}

Он является альтернативным способом получения желаемого результата:

Давайте создадим словарь, который указывает, появилось ли число в h:

var dict = [Int: Bool].init(minimumCapacity: h.count)
for x in h {
    if dict[x] == nil {
        dict[x] = true
    }
}

А затем, для каждого элемента h, убедитесь, что его преемник появляется в словаре:

var count = 0

for entry in dict {
    if dict[entry.key + 1] == true {
        count += 1
    }
}

И вы можете проверить результат:

print(count) //4
...