Как найти случайный индекс в массиве A, значение которого не появляется в массиве B?
Допустим, массив A содержит это:
[0, 1, 8, 3, 10, 6, 2]
И массив B содержит это:
[1, 2]
Как я могу генерировать случайный индекс в массиве A, значение которого не появляется в массиве B? Возможные индексы в приведенном выше примере:
0, 2, 3, 4, 5
Но как это сделать в Swift?
3 ответа
Когда вы хотите работать с элементами массива и их индексами, enumerated()
может быть хорошим инструментом:
var a = [0, 1, 8, 3, 10, 6, 2]
var b = [1, 2]
var possibleIndices = a.enumerated()
.filter{!b.contains($0.element)}
.map{$0.offset}
print(possibleIndices)
//->[0, 2, 3, 4, 5]
(Когда b
может быть большим, лучше сделать это Set
.)
А потом:
(Когда мы можем предположить, b
никогда не содержит все содержимое a
.)
var randomIndexToPossibleIndices = Int(arc4random_uniform(UInt32(possibleIndices.count)))
var randomIndex = possibleIndices[randomIndexToPossibleIndices]
Если вышеуказанное предположение не может быть выполнено, possibleIndices
может быть пустым. Так что тебе лучше сделать randomIndex
Необязательный:
var randomIndex: Int? = nil
if !possibleIndices.isEmpty {
var randomIndexToPossibleIndices = Int(arc4random_uniform(UInt32(possibleIndices.count)))
randomIndex = possibleIndices[randomIndexToPossibleIndices]
}
Спасибо за Мартина Р.
Как насчет работы с сетами?
let a = [0, 1, 8, 3, 10, 6, 2]
let b = [1, 2]
var setA = Set(a)
var setB = Set(b)
setA.subtract(setB)
var index: Int? = nil
if let first = setA.first {
index = a.index(of: first)
}
// if index == nil no such index exists
Во-первых, вам нужно сгенерировать diff между двумя массивами (если только они оба не очень большие, в этом случае случайная попытка рекурсивной проверки может привести к повышению производительности).
Тогда все, что вам нужно сделать, это найти случайный индекс, который вы хотите использовать, и получить доступ к указанному элементу:
#if os(Linux)
let j = Int(random() % ((count-1)))
#else
let j = Int(Int(arc4random()) % ((count-1)))
#endif
Даст вам правильный индекс
Если вы затем используете этот индекс и элемент для поиска оригинального элемента в вашем массиве, вы получите свой результат.
Если в случае, если ваши элементы являются целыми числами и, следовательно, могут возникать коллизии, то я бы рекурсивно нашел их для решения вашей проблемы. Помните, что это может привести к снижению производительности.
Посмотрите на функциональное программирование коллекций в swift здесь: Swift Руководство по уменьшению фильтра карт
Например, вы можете использовать фильтр следующим образом (и я не знаю, является ли это лучшим способом):
collection.filter {
var found = false;
for element in bCollection {
if element == $0 {
found = true;
}
}
return !found; // Might be better to turn true/false thing around in the above code to slightly improve performance.
}