По сути это тот же вопрос, что и
Джулия: Сглаживание массива/кортежей
но для массива String. Решение Iterators.flatten(xs), показанное в теме выше, отлично подходит для чисел. Но с помощью StringsIterators.flatten() превращает String в символы!
julia> f(xs...) = collect(Iterators.flatten(xs))
f (generic function with 1 method)
julia> f("oh", ["a", "b"], "uh")
6-element Vector{Any}:
'o': ASCII/Unicode U+006F (category Ll: Letter, lowercase)
'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)
"a"
"b"
'u': ASCII/Unicode U+0075 (category Ll: Letter, lowercase)
'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)
Как получить массив Strings
"oh"
"a"
"b"
"uh"
из приведенного выше вызова f()?
Было бы неплохо, если бы вы могли указать итератору считать String скаляром.



Не совсем уверен, существует ли встроенная функция, способная это сделать, но написать ее самостоятельно не так уж и сложно. Может быть, что-то вроде этого:
function custom_flatten(xs...)
result = String[]
for x in xs
if isa(x, AbstractArray) || isa(x, Tuple)
append!(result, custom_flatten(x...))
else
push!(result, x)
end
end
return result
end
xs = ["hello", ["a", "b"], "world", [["nested"], "array"]]
flattened = custom_flatten(xs...)
println(flattened)
# Output: Any["hello", "a", "b", "world", "nested", "array"]
Вы также можете добавить проверку, является ли элемент string, и выдать ошибку или что-то в этом роде, поскольку вы запросили массив строк.
@DNF Да, конечно. Поскольку это было общее решение, я не хотел связывать тип возвращаемого значения, но поскольку OP запрашивал массив строк, я мог бы изменить его. Спасибо.
Спасибо, @DNF и @Milos Stojanovic, но что не так с нетипизированным контейнером? Решение Милоса работает для других типов, и иногда это то, что хочется Iterators.flatten(), потому что Милос полностью сглаживает, тогда как стандарт flatten просто удаляет один слой «контейнерности».
@Ryo Как правило, использование типизированных контейнеров может повысить производительность, читаемость, эффективность использования памяти, предотвращение ошибок и т. д. Короче говоря, если вы знаете, что ваш массив будет содержать только строки, полезно правильно его типизировать и не допускать, чтобы он содержал что-либо еще.
Вместо сбора передайте вывод Flatten в генератор списка:
f( xs... ) = [ string(i) for i in Iterators.flatten( xs ) ]
Извините, что мой первоначальный вопрос был двусмысленным. Я только что переписал его. Ваше решение - одно из решений моего первоначального неоднозначного вопроса.
Избегайте нетипизированных контейнеров. Вместо
result = []напишитеresult = String[].