如何定义单函数实现任意维度AbstractArray的灵活view索引操作?
实现方案
你想要的N维通用版本可以用一行代码实现,完全匹配你的需求:
view_something(A::AbstractArray, ind) = view(A, ntuple(_ -> :, ndims(A)-1)..., ind)
原理解释
ndims(A)可以动态拿到输入数组的维度ntuple(_ -> :, ndims(A)-1)会生成一个长度为「数组维度减1」的元组,每个元素都是Colon()也就是你说的:索引符- 用
...把生成的冒号元组展开,再把索引ind放在最后,就实现了前N-1维全选、最后一维按给定索引切片的效果,完全兼容任意维度的数组。
关于你提到的Colon拼装方案的疑问
你想到的通过拼装Colon()数组/元组的实现思路是完全正确且Julia官方推荐的标准实现方式,这种写法的性能和你手写多个维度的多分派版本完全一致,因为ntuple是编译期展开的,不会引入任何运行时开销,不存在更优的其他方案。
验证测试
你可以用下面的代码验证实现的正确性,和你原来的三个函数效果完全一致:
ind = 1:5 # 1维数组测试 @assert size(view_something(rand(10), ind)) == (5,) # 2维数组测试 @assert size(view_something(rand(10,10), ind)) == (10,5) # 3维数组测试 @assert size(view_something(rand(10,10,10), ind)) == (10,10,5)
如果后续需要修改为对其他固定位置的维度做切片,只需要调整ntuple的生成逻辑即可,比如要对第k维做切片,就生成k-1个冒号放在前面,剩下的ndims(A)-k个冒号放在ind后面即可。
内容的提问来源于stack exchange,提问作者max xilian
相关产品推荐
相关产品推荐

