对于这类问题,我发现定义 .in. 运算符很方便,它返回标量是否在数组中,所以:
-
1 .in. [0, 1, 2] 返回.true.
-
3 .in. [0, 1, 2] 返回.false.
-
[1, 3] .in. [0, 1, 2] 返回[.true., .false.]
这可以定义为
module in_module
implicit none
interface operator(.in.)
module procedure element_in_list
module procedure elements_in_list
end interface
contains
function element_in_list(lhs, rhs) result(output)
integer, intent(in) :: lhs
integer, intent(in) :: rhs(:)
logical :: output
output = any(lhs==rhs)
end function
function elements_in_list(lhs, rhs) result(output)
integer, intent(in) :: lhs(:)
integer, intent(in) :: rhs(:)
logical, allocatable :: output(:)
integer :: i
output = [(any(lhs(i)==rhs), i=1, size(lhs))]
end function
end module
定义 .in. 运算符后,如果 X 是一个数组,您可以编写
where (.not. (X .in. [0, 1, 2, 16, 18])) X = -9999
这将转换例如X = [4, 5, 1, 3, 16] 到 X = [-9999, -9999, 1, -9999, 16]。
如果您想进一步简化事情(因为where 构造可能非常笨拙),您还可以定义函数filter,它接受一个逻辑数组并返回.true. 值的索引,例如filter([.false., .true., .true.]) 返回[2, 3]。
这可以定义为:
function filter(input) result(output)
logical, intent(in) :: input(:)
integer, allocatable :: output(:)
integer :: i
output = pack([(i, i=1, size(input))], input)
end function
然后你可以简单地写
X(filter(.not. (X .in. [0, 1, 2, 16, 18]))) = -9999