 # How can I get immediate greater and lesser value of a number

value = 7
jobs = [1, 4, 9, 3, 8, 6, 2]
output should be 6,8
i have large and too many lists. please suggest me optimised solutions.

``````jobs = [1, 4, 9, 3, 8, 6, 2]
num = 7
Enum.reduce(jobs, {nil, nil}, fn
e, {nil, max} when e < num -> {e, max}
e, {min, nil} when e > num -> {min, e}
e, {min, max} when e > min and e < num -> {e, max}
e, {min, max} when e < max and e > num -> {min, e}
_, min_max -> min_max
end)
``````

The idea is you walk through the list narrowing down the difference. Maybe this looks shorter:

``````Enum.reduce(jobs, {nil, nil}, fn
e, {min, max} when (is_nil(min) or e > min) and e < num -> {e, max}
e, {min, max} when (is_nil(max) or e < max) and e > num -> {min, e}
_, min_max -> min_max
end)

``````
2 Likes

So for any given `n`, do you always want to check if `n-1` and `n+1` are in the list, or do you search those `x` for that holds that there is no `y` greather than `x` and lesser than `n` (and the other way round for the other side)?

edit

Perhaps my last sentence could be better phrased as “…or do you want to search for the greatest number smaller than `n` as well as the smallest number greater than `n`?”

another edit

If it is the first, I’d roughly do

``````def search(n, list) do
Enum.filter(list, & &1 in [n-1, n+1])
end``````
1 Like

Due to Erlang term ordering (i.e. `number < atom`) you can get away with:

``````Enum.reduce(jobs, {nil, nil}, fn
e, {min, max} when e < max and e > num -> {min, e}
e, {min, max} when (is_nil(min) or e > min) and e < num -> {e, max}
_, min_max -> min_max
end)
``````

or

``````Enum.reduce(jobs, {nil, nil}, fn
e, {nil, max} when e < num -> {e, max}
e, {min, max} when e > min and e < num -> {e, max}
e, {min, max} when e < max and e > num -> {min, e}
_, min_max -> min_max
end)
``````

perhaps sacrificing some clarity.

Yeah, I know. I would even go with my first snippet because I value clarity way more than brevity.

1 Like

not greatest, smallest. just want to get next and previous numbers.

So if you only want to see `n-1` and `n+1` my solution should suffice. You can microoptimise it though by using `Enum.reduce` or even `List.fold`. Also by precalculating `n-1` and `n+1` outside of the closure.

But I’m not sure if that will shave much…