In fact there are just two values: the one with index returned by I. and
the one before it. The following version returns a single value,
breaking ties by choosing the smaller element:
nearest =: ] (] {~ [: >/ |@-) (_,~[) {~ (,~<:)@:I.
1 5 8 9 nearest 4
5
1 5 8 9 nearest _3
1
1 5 8 9 nearest 10
9
1 5 8 9 nearest 3
1
Note that _ has to be appended to the list before selection to avoid an
index error if the given number is larger than any of the array
elements. It is actually selected for that case and the case where the
given number is smaller than the entire list, since that means I.
returns 0 and we have an index of _1. But _ is further from any real
number than any other real number is, so it can't be returned.
Marshall
On Mon, Jun 01, 2015 at 09:38:14PM -0400, Raul Miller wrote:
> If you know that your values are sorted, you could use I. to get an
> initial approximation (a set of up to three values) and then use brute
> force to pick from them.
>
> This assumes also that you want a single value (or index).
>
> This also winds up being more code than the other proposals I've seen
> here. So I'm not sure if it's "worth it".
>
> --
> Raul
>
>
> On Mon, Jun 1, 2015 at 9:02 PM, Joe Bogner <[email protected]> wrote:
> > Is there a more efficient, idiomatic method of finding the nearest
> > (absolute difference) x to y?
> >
> > nearest=:([ {~ {.@/: @: |@:-)
> >
> > 1 5 8 9 nearest 4
> > 5
> >
> > 1 5 8 9 nearest 6
> > 5
> >
> > 1 5 8 9 nearest 5
> > 5
> >
> > 1 5 8 9 nearest 2
> > 1
> >
> > This seems to work fine but was curious if there is a more common solution
> > ----------------------------------------------------------------------
> > For information about J forums see http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm