Skip to content

Searching

Find with vectors is intuitive. With general lists, not so much.

Find

Where x is a list

x?y   / finds the first occurrences of y in x
The result is an atom or list of long integers. Where (an item of) y is not found, the index returned is count[x].
q)"bad beef"?"bread"
0 8 5 1 2

Simple cases

Where x and y are both vectors, or both general lists, atoms are matched with atoms, or items with items.

q)0 1 1 2 3 5 8 13 21 34 55? 8 2 13 -1
6 3 7 11
q)("pain";"viande";"legumes")?("pain";"perdu")
0 3
Where x is a vector and y is a list, Find is right-atomic.
q)`the`glory`that`was`rome?(`rome`glory;(`was`that;`glory);`really)
4 1
(3 2;1)
5
Where x is a general list and y is a vector, Find looks for y as an item of x.
q)("cow";"sheep";42;`skidoo)?"sheep"
1
For searching vectors and lists of vectors, these rules suffice. For general rules, keep reading.

Matching rules

The matching rules apply to all kinds of lists, not just vectors and lists of vectors. For general lists, the results can be counter-intuitive.

The first items of the arguments determine what gets matched.

A general list can have an atom as its first item.

Matching rules according to the first items of x and y:

atom ? atom

Items of x are matched to items of y.

q)0 1 1 2 3 5 8 13 21 34?8 7 1 1          / vector - vector
6 10 1 1

q)("b";"string";"x";"i")?("x";"string")   / general list - general list
2 1

q)("b";"string";"x";"i")?"x"              / general list - atom
2
q)("b";"string";"x";"i")?"string"         / general list - vector
4 4 4 3 4 4 
atom ? list

Items of x are matched to atoms of y. Find is right-atomic.

q)"strings"?("st";"ring")                 / vector - general
0 1
2 3 4 5
q)("s";"t";"ring";"s")?("st";"rings")     / general - general
0 1
4 4 4 4 0
Vector – general list: type error

Where x is a vector and y is a general list whose first item is an atom, or that contains such a general list, Find signals a type error.

q)"bad beef"?("bee";("bead";"b");"abed")
0 5 5
(0 5 1 2;0)
1 0 5 2
q)"bad beef"?("bee";("b";"bead");"abed")
'type
  [0]  "bad beef"?("bee";("b";"bead");"abed")
                 ^

list ? atom

Items of x are matched to the whole of y; i.e. x~\:(),y.

q)("st";"ring";"s")?"ring"
1
q)("st";"ring";"s")?("s";"ring";"st")
3
Notice that an atom y is enlisted for matching.
q)("st";"ring";"s")?"s"     / not found
3
q)("st";"ring";(),"s")?"s"  / found
2

So there is no way to match an atom item in x.

list ? list

Items of x are matched to items of y.

q)("cow";"sheep";"cat";"dog")?("cat";"cow")
2 0
Tables are lists.
q)t
name age eyes  hair
--------------------
tom  31  blue  fair
raja 33  brown black
emil 27  green brown
xin  33  brown black
q)u
name age eyes  hair
--------------------
xin  33  brown black
raja 33  brown black
ken  35  blue  fair
q)t?u
3 1 4

Summary:

x[0] | y[0] | items of x matched to
-----|------|----------------------
atom | atom | items of y
atom | list | atoms of y
list | atom | (),y
list | list | items of y

String searches

The Find operator can locate entire strings:

q)("cow";"sheep";"cat")?"sheep"
1
q)("cow";"sheep";"cat")?("sheep";"dog")
1 3
or characters within a string:
q)"she looked sheepish"?"she"
0 1 2
The string-search keyword ss finds substrings within a longer string:
q)"she looked sheepish"ss"she"
0 11
or a pattern.
q)"sea shells"ss"s??"
0 4
The like keyword reports whether one or more strings x match a pattern y.
q)("she";"sells";"sea";"shells")like"sh*"
1001b
q)"shell"like"sh*"
1b
Regular expressions in q


Exercises

No peeking.

Attempt each exercise before looking at its answer.

The exercises clarify your thinking. Reading answers does not.

qbf:"thequickbrownfoxjumpsoverthelazydog"
sss:string`she`sells`sea`shells`by`the`sea`shore
  1. Predict the results of

    0 1 1 2 3 5 8 13 21 34?55 5 1
    sss?("sea";"saw")
    sss?"shells"
    
    Answer
    q)0 1 1 2 3 5 8 13 21 34?55 5 1
    10 5 1
    q)sss?("sea";"saw")
    2 8
    q)sss?"shells"
    3
    
  2. Predict the results of

    count each qbf?("the";("strings";"of");"saturn")
    count each qbf?("a";("ring";"of");"saturn")
    ("a";("ring";"of");"saturn")?qbf
    
    Answer

    q)qbf?("the";("strings";"of");"saturn")
    0 1 2
    (20 0 9 5 12 34 20;10 13)
    20 29 0 4 9 12
    
    q)count each qbf?("the";("strings";"of");"saturn")
    3 2 6
    
    q)count each qbf?("a";("ring";"of");"saturn")
    'type
      [0]  count each qbf?("a";("ring";"of");"saturn")
    
    q)("a";("ring";"of");"saturn")?qbf
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 0 3 3 3 3 3
    
    The third example signals a type error because the nested-list right argument contains an atom item.

    In the fourth example, the first item of x is an atom, so items of x are matched to items of y – in this case, atoms. Only the "a" matches an item of x.

  3. Write a lambda or composition fp that works like Find but matches strings using q’s limited pattern matching instead of Match, so that

    q)fp[sss;"sh*"]
    0 3 7
    
    Answer
    fp:('[where;like])   / {where x like y}