Hi all, im trying to write a function to find the max value of a list without using the ‘max’ function itself. im trying to put into the function - if any element of the list is greater than or equal to all the other elements, then please return that element. I have a snapshot below. I know if statements dont return values, but i just coded it this way to show you what im trying to get at. Thank you in advance of your help
Be wary that KDB executes right to left and this looks like you are trying to run before you can walk. Try to build the function up gradually and learn as you go. Breaking down what you’ve got so far:
show a 296 216 717 414 657 890 407 635 108 652 // this executes first, all will basically return 0 or 1b if all values are true. In the case of number this is if they are 0 or not all a 1b // compares if a is >= 1 (1b) a >= all a 1111111111b // any shows if there are any values in the list which are true so you are basically going in a circle any a >= all a 1b // if does not return anything like a $ conditional does so your function actually returns nothing q){ if[any x>=all x;x]} a q) // if you add a colon it will just return a/x back to you q){ if[any x>=all x;:x]} a 296 216 717 414 657 890 407 635 108 652
To do this without max you need to take each number in the list and compare it to the others to see if it’s the greatest:
// there are many ways to do this but here’s one way: myMax:{[list] first list where {[list;num] all num >= list }[list] each list} // list where {condition / list of booleans same length as list } // will return the items in the list which are true. // first will return an atom first list where // this part of the function takes each item in the list // compares it with the whole list to see if it’s >=. // all then returns true if it is greater/equal to all of them and therefore is the max {[list;num] all num >= list }[list] each list} myMax a 890 // could also cheat and just do greater/or(|) and over(/) (|/) a 890 https://code.kx.com/q/ref/over/https://code.kx.com/q/ref/greater/
In APL max is ?/, which in q is |/. APL implementers optimise for different datatypes, which I suppose the q implementers do beneath the covers of max.
Your idea: compare each item of a to the others; pick whichever is At Least >= all the others.
q)a 296 216 717 414 657 890 407 635 108 652 q)a >=\:/: a 1011111101b 1111111101b 0010010000b 0011110101b 0010110000b 0000010000b 0011111101b 0010110101b 1111111111b 0010110001b q)a first where (and/)a >=\:/: a 890
Or you could exploit qs sort.
q)first desc a 890
A pity to sort the whole list just to pick one item. We could lighten up a little by using idesc.