Julia equivalent of the IDL WHERE() function?


#1

Having programmed mostly in IDL before coming to Julia, is there a command similar to IDL’s WHERE() function? The WHERE() function returns an array of indeces given a certain condition, so in IDL I could write:

> day = ["mon","tue","wed","mon"]
> index = where(day eq "mon" or day eq "tue")
> print,day[index]
mon tue mon

I just don’t know the best way to achieve a similar result with Julia.

Thanks in advance for your help!
Michael


#2

This works:

julia> day = ["mon","tue","wed","mon"]
4-element Array{String,1}:
 "mon"
 "tue"
 "wed"
 "mon"

julia> idx = find(x -> x in ["mon", "tue"], day)
3-element Array{Int64,1}:
 1
 2
 4

#3

Hi Michael,
I can give you a straight forward version using ->dots

day = ["mon","tue","wed","mon"]
index = (day .== "mon") .| (day .== "tue")
day[index]
3-element Array{String,1}:
 "mon"
 "tue"
 "mon"

and a “modern” solution using ->generators with if clause

collect(d for d in day if d == "mon" || d == "tue")

Best


#4

Thanks for the quick responses. I will test out the choices in my code and see which one makes the most sense to use.


#5

I tested out the codes you supplied, and the dots version worked, but the version with collect() gave me a synatx error, “missing comma or ) in argument list”. I am using Julia version 0.4.5 (supplied by Ubuntu repos). I would probably use the dots the version anyway, but would the error be related to the julia version I am using?


#6

Yes, the collect generator version should work with v0.5 or higher.

And here’s yet another alternative:

filter(d -> d == "mon" || d == "tue", day)

#7

I would really recommend to get a more up to date version than 0.4. Tremendous improvements have been done on the language since then. You can just download it from https://julialang.org/downloads/, extract it and run the executable in the bin folder.


#8

@mihalybaci please follow @kristoffer.carlsson’s advise and get a decently recent version of Julia.


#9

Yet another option:

julia> day = ["mon","tue","wed","mon"]
julia> ind = findin(day, ["mon", "tue"])
julia> day[ind]
3-element Array{String,1}:
 "mon"
 "tue"
 "mon"

#10

I would say that find or findin are the most correct answers to this question as written. They are equivalent to the WHERE function in that they return an array of indices.

The other approaches (filter, generator, and the logical index) don’t do that. But perhaps the what the OP really wanted was finding the elements themselves, and only wanted WHERE as an intermediate step?


#11

I have thought about it, but have stuck with the Ubuntu 16.04 repos just to make sure everything works, but I will test out the latest stable binary,

As for my intent, I do need an array of indices so that I can feed it into another array to pick out subsets, and the original post is really a simple version of what I’d like to do in the future. For instance, if I have a catalog of star positions (x,y) and I wanted to pick out all the sources within a circlular area given by (x_center,y_center,radius) I could write this

> c = where(sqrt((x - x_center))^2. + (y - y_center)^2.) le radius/60.)
> print,star_names[c]
Betelgeuese

where x and y are separate arrays and “le” is less than or equal to.


#12

Yeah, I completely understand that using whatever the distro supplies is the most convenient way. I would argue that there is a failure from our side that there is such an outdated PPA available. It should either not be there at all, or be updated in a timely manner with new Julia versions.


#13

@mihalybaci, given the number of alternative solutions you have, what about creating an answer where you collect all the alternatives? It is great to see so many clean solutions for the same task, putting them all together would facilitate comparison and show the syntax strengths for new comers. :slight_smile:


#14

@juliohm, I was considering running a few tests to see if there were any appreciable speed differences between the methods for what I intend to do. If I get around to it, I could add the results here.