В R есть функция replace(A, I, B), которая заменяет значения в A с индексами, заданными в I, на значения, заданные в B (B может быть скаляром). Как проще всего это сделать в Джулии?
Да, он выполняет эту базовую функцию, но полезен для изменения переменной внутри такой функции, как f(replace()).
Я добавил ответ ниже, который отвечает на ваш вопрос, просто создав новую функцию - не похоже, что есть встроенная функция, которую вы ищете.
Итак, вы хотите что-то вроде replace в R, что не обновляет исходный вектор, а создает его копию, обновляет и возвращает измененную копию?
Да, функция setindex(), представленная в приведенном ниже ответе @ahnlabb, работает, но не для скаляров.



Обычно это можно сделать с помощью присвоения по индексу:
array = [0,2,3]
array[1] = 1
# array is now [1,2,3]
Выше вы упомянули о необходимости функции, а также о возможности изменения нескольких индексов.
Это не функция в Base, но сделать это самостоятельно довольно сложно.
# Make a base function. Error catching is optional but included here.
function replace!(ar::Vector,i::Int,val)
i<0&&error("Index must be non-negative")
i>size(ar)[1]&&error("Index out of range")
ar[i]=val
end
# Extend function for use on vector inputs
function replace!(ar::Vector,i::Vector{Int},val::Vector)
size(i)!=size(val)&&error("Must have same number of indices and values")
for j in 1:size(i)[1]
replace!(ar,i[j],val[j])
end
end
# Example Below
myArray = [9,9,9,9,9]
replace!(myArray,1,5)
# MyArray is now [5, 9, 9, 9, 9]
replace!(myArray,[2,3,4],[6,7,8])
# MyArray is now [5, 6, 7, 8, 9]
Это использует функцию множественной отправки Джулии, где функция может быть определена по-разному для разных входных параметров. Это основная функция, которая делает код очень понятным.
Имейте в виду, что если вы знаете, какие данные будет содержать входной массив, вы можете изменить это, чтобы расширить массив, если вы введете слишком высокий индекс, заполнив его некоторым значением-заполнителем, но это не было запрошено, поэтому это не было включено.
Соответствующая функция в Julia — setindex!:
setindex!(A, X, inds...)Сохраните значения из массива X в некотором подмножестве A, как указано в inds. Синтаксис
A[inds...] = Xэквивалентен(setindex!(A, X, inds...); X).
Пример в РЕПЛ:
julia> A = [1,2,3,4,5]; I = [1,3]; B = [100, 101];
julia> setindex!(A, B, I);
julia> A
5-element Vector{Int64}:
100
2
101
4
5
Обратите внимание, что setindex! изменяет аргумент. Мы можем использовать copy для выделения нового массива.
julia> setindex(A, X, inds...) = setindex!(copy(A), X, inds...)
setindex (generic function with 1 method)
julia> A = [1,2,3,4,5]; B = [100, 101]; I = [1,3];
julia> setindex(A, B, I)
5-element Vector{Int64}:
100
2
101
4
5
julia> A
5-element Vector{Int64}:
1
2
3
4
5
Этот ответ неверен. Это терпит неудачу, когда B является скалярным, как спрашивает OP. Имо, это также неидиоматично. Правильный и идиоматический ответ A[I] .= B
Определенно согласен, что это не идиоматично. Я редко использовал/видел setindex! за исключением перегрузки оператора. Я интерпретирую вопрос и комментарий OP как вопрос о функции в стандартной библиотеке, которая является близким аналогом replace. Оба широковещательных assign и setindex! не могут полностью соответствовать, поскольку replace R не мутирует, но широковещательное присваивание возвращает материализованный массив вместо обновленного массива LHS. A[I] .= B в настоящее время анализируется как: broadcast!(identity, Broadcast.dotview(A, I), B) поэтому не соответствует функции в Base. Я расширю ответ и назову ваш идиомой.
Ответ прост:
A[I] .= B
Если вы посмотрите на источник
replace, это единственныйx[list] <- values. Так можетA[I] = B?