Re: Locate function for logical array
- From: "robin" <robin51@xxxxxxxxxxxxxxxxxx>
- Date: Wed, 26 Jan 2011 14:54:07 +1100
"jfh" <john.harper@xxxxxxxxx> wrote in message news:62c60c6e-dbb2-488e-ac49-6fba4e2bb1ee@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
~On Jan 24, 1:17 pm, glen herrmannsfeldt <g...@xxxxxxxxxxxxxxxx> wrote:
~> Dave Allured <nos...@xxxxxxxxxx> wrote:
~> > I am seeking a function that is like the "index" function for strings,
~> > except for a 1-D logical array. Is there an intrinsic function or more
~> > elegant coding method to do this, rather than an explicit loop? It
~> > "seems" to me that there ought to be a nicer way in fortran.
~> > integer i, p
~> > logical x(6)
~> > x = (/.false.,.false.,.true.,.false.,.true.,.false./)
~> > p = 0
~> > do i = 1, 6
~> > if (x(i)) then
~> > p = i
~> > exit
~> > end if
~> > end do
~> Otherwise, you can write a logicalindex function pretty easily.
~> You do need two loops, though.
~> You could make strings of 'T' and 'F', and then use index.
~The following program shows and tests a way to do it in F95 without
~having to write the loops oneself, though they are presumably "under
~the hood" of the intrinsics used. BTW, I used the variable reallyback
~to work around a bug in one of the compilers I tried, which wouldn't
~let an absent dummy argument be used as an actual optional argument,
~in spite of the F95 standard 22.214.171.124 and F2003 standard 126.96.36.199. I
~reported the bug to the compiler's developers some time ago. They may
~have fixed it by now, but our systems people haven't yet installed the
~latest version of that compiler.)
~ implicit none
~ logical,parameter:: &
~ larray(6) = (/.false.,.true.,.false.,.true.,.true.,.false./),&
~ farray(2) = larray(1:3:2)
~ print *,larray,lindex(larray)
~ print *,farray,lindex(farray)
~ print *,larray,lindex(larray,.true.)
~ print *,farray,lindex(farray,.true.)
~ print *,larray,lindex(larray,.false.)
~ print *,farray,lindex(farray,.false.)
~ integer function lindex(larray,back) ! Pos. of first(last) true element
~ logical,intent(in) :: larray(:)
~ character(size(larray)) :: string
~ logical:: reallyback = .false.
~ if(present(back)) reallyback = back
~ lindex = index(transfer(merge('T','F',larray),string),'T',&
~ end function lindex
~end program logicalindex
Obfuscation of the task -- such as provided in that "solution" --
is to be abhorred.
The simple, straight-forward, uncomplicated, unequivocal solution
offered by the OP is preferred. It is doubtful that it can be bettered.