Problem to check whether all elements of a text wave are equal

Dear all,

I have tried to construct a procedure which returns whether all strings in a 1D-textwave are equal.
This is what I did:

// Handy function to check whether two string variables are equal
Function AreEqual_str(str1,str2)
String str1, str2
if(cmpstr(str1,str2)==0)
    return 1
else
    return 0
endif
End

// Handy function to check whether all elements of a text wave are equal
// returns "0" if not all strings in the text wave are equal
Function TextWaveEqual(Textwave)
Wave /T Textwave
Variable NOP = numpnts(TextWave)
Variable counter, result
String Str1,Str2
for(counter=0;(counter+1)<NOP;counter+=1)
    Str1 = TextWave [counter]
    Str2 = TextWave [counter+1]
    if(AreEqual_str(Str1,Str2)==0)
        Break
        return 0
    endif
endfor
End


The problem now is, that the function always only returns NaN, and I can't figure out why...

Any help would be highly appreciated :)

Regards,
Peter
A function that returns a numeric value, such as your TextWaveEqual(), will return NaN by default unless instructed to return a different value. In the case where all values in the wave are equal, TextWaveEqual() will return NaN because you are not telling it to return a different value. Try adding return 1 just before the end of the function.

In case it matters, CmpStr does a case insensitive comparison by default.
Thanks for the reply!

The function returns Nan in any case, whether all elements are equal or not...

I tried return 1, but it overwrites the return 0, so that the function always returns 1...

Maybe I could return 1 by default, and only return 0, when the loop breaks...
Ok now this seems to work:

// Handy function to check whether all elements of a text wave are equal
// returns "0" if not all strings in the text wave are equal
Function TextWaveEqual(Textwave)
Wave /T Textwave
Variable NOP = numpnts(TextWave)
Variable counter, result
String Str1,Str2
for(counter=0;(counter+1)<NOP;counter+=1)
    Str1 = TextWave [counter]
    Str2 = TextWave [counter+1]
    if(AreEqual_str(Str1,Str2)==0)
        result = 0
        Break
    else
    result = 1
    endif
endfor
return result
End


Thanks for the input, aclight!
PeterR wrote:
Ok now this seems to work: ...


Unless I am missing something, your function will return 1 any time two places in the text wave are the same. Perhaps this is what you mean ...

Function CheckAllEqual(twave)
    wave/T twave
   
    variable np, ic, cne, re
    np = numpnts(twave)
    for (ic=0;ic<np-1;ic+=1)
        cne = ((cmpstr(twave[0],twave[ic+1]))==0) ? (cne+1) : cne
    endfor
    re = cne == np-1 ? 1 : 0
    return re
end

make/N=10/T samewave ="bla"
make/N=10/T diffwave = num2str(mod(p,2))

print CheckAllEqual(samewave) --> 1
print CheckAllEqual(diffwave) --> 0

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
This should be faster (validity not tested) ...

Function CheckAllEqual(twave)
    wave/T twave
 
    variable npts = numpnts(twave), re

    make/FREE/N=(npts) iwave
    iwave = cmpstr(twave[0],twave[p]) == 0 ? 1 : 0
    re = sum(iwave) == npts ? 1 : 0

    return re
end


Someone at Wavemetrics (AG) may offer a MatrixOp to compete in speed :-)

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
Just tested my original function, it returns correct values for all imaginable cases :) But thanks anyway for the input!
jjweimer wrote:

Someone at Wavemetrics (AG) may offer a MatrixOp to compete in speed :-)


Since you asked:
Function CheckAllEqualMO(twave)
    wave/T twave
 
    variable npts = numpnts(twave)
 
    make/FREE/N=(npts) iwave
    String first=twave[0]
    iwave = cmpstr(first,twave[p])        // this is the main difference!
    MatrixOP/O/FREE aa=sum(iwave)   // you did ask for MatrixOP... :)
    return aa[0]-npts==0
end


MatrixOP is strictly numeric which suggests that you might do better converting the text wave entries into unique numerical representation and then using MatrixOP. StringCRC does not appear to be very efficient.

A.G.
WaveMetrics, Inc.
You could also use grep and the /INDX and /Q flags, grepping against the first entry. This will give you a wave called W_index, from which you can ascertain the number of equal strings.

A.
PeterR wrote:
Just tested my original function, it returns correct values for all imaginable cases :) But thanks anyway for the input!


Oh. I see now why.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
I think cmpstr also works for text waves comparison. Not sure this is intended or not.