Как вы назначаете часть чисел массиву в Swift?
x
является объектом, который содержит массив с именем point.
x
реализует оператор индекса, чтобы вы могли делать такие вещи, как x[i]
чтобы получить i-й элемент массива (типа T, который обычно является Int или Double).
Вот что я хочу сделать:
x[0...2] = [0...2]
Но я получаю ошибку, которая говорит ClosedInterval<T>
не конвертируется в Int / Double.
Edit1:
Вот мой объект x
:
let x = Point<Double>(dimensions:3)
Для ударов ногами: определите x
как [1.0,2.0,0.0]
Я могу получить первый n
элементы через x[0...2]
,
Что я хочу знать, так это как обновить x[0...2], чтобы удерживать [0.0, 0.0.0.0] одним махом. Интуитивно я бы хотел сделать x[0...2] = [0...2]
, Это не работает, как видно из ответов. Я хочу обновить x
без итерации (с моей стороны) и скрывая тот факт, что x
не является массивом (хотя это не так).
2 ответа
[0...2]
массив с одним элементом, который, в лучшем случае, будет Range<Int>
от 0 до 2. Вы не можете назначить это слайсу, содержащему, скажем, Int
s.
x[0...2]
с другой стороны, это (вероятно) срез, и Sliceable
только определяет get
нижний индекс, а не сеттер. Так что, даже если типы были более совместимы - то есть, если вы пытались x[0...2] = 0...2
который, по крайней мере, пытается заменить диапазон в x
с ценностями коллекции одинакового размера - это все равно не сработает.
edit: как указывает @rintaro, Array поддерживает нижний индекс сеттера для диапазонов - так что если x
был диапазон, который вы могли бы сделать x[0...2] = Slice(0...2)
- но это должен быть фрагмент, который вы назначаете, так что я бы все равно replaceRange
,
Если вы имеете в виду, что вы хотите заменить записи с 0 по 2 на некоторые значения, то вы хотите, чтобы replaceRange
до тех пор, пока ваша коллекция соответствует RangeReplaceableCollection
(который, например, Array
делает):
var x = [0,1,2,3,4,5]
var y = [200,300,400]
x.replaceRange(2..<5, with: y)
// x is now [0,1,200,300,400,5]
Обратите внимание, замененный диапазон и y
не должен быть того же самого размера, коллекция будет расширяться / сокращаться по мере необходимости.
Также, y
не должен иметь массив, это может быть любая коллекция (хотя должна быть коллекция, а не последовательность). Таким образом, приведенный выше код мог быть записан как:
var x = [0,1,2,3,4,5]
var y = lazy(2...4).map { $0 * 100 }
x.replaceRange(2..<5, with: y)
edit: так, в соответствии с вашими правками, чтобы обнулить массив любого размера за один раз, вы можете сделать:
var x = [1.0,2.0,0.0]
// range to replace is the whole array's range,
// Repeat just generates any given value n times
x.replaceRange(indices(x), with: Repeat(count: x.count, repeatedValue: 0.0))
Настройте диапазон (и количество заменяющих записей) соответственно, если вы хотите просто обнулить поддиапазон.
Учитывая ваш пример Point
Класс, вот как вы могли бы реализовать это поведение, если оно поддерживается массивом изнутри:
struct Point<T: FloatLiteralConvertible> {
private var _vals: [T]
init(dimensions: Int) {
_vals = Array(count: dimensions, repeatedValue: 0.0)
}
mutating func replaceRange
<C : CollectionType where C.Generator.Element == T>
(subRange: Range<Array<T>.Index>, with newElements: C) {
// just forwarding on the request - you could perhaps
// do some additional validation first to ensure dimensions
// aren't being altered...
_vals.replaceRange(subRange, with: newElements)
}
}
var x = Point<Double>(dimensions:3)
x.replaceRange(0...2, with: [1.1,2.2,3.3])
Вам необходимо реализовать subscript(InvervalType)
обрабатывать случай нескольких назначений, как это. Это не сделано для вас автоматически.