# 2 lines in one

**URL:** <https://www.ruby-forum.com/t/2-lines-in-one/88263>\
**Category:** Ruby\
**Created:** [March 9, 2007, 8:51am UTC](https://www.ruby-forum.com/t/2-lines-in-one/88263 "2007-03-09T08:51:14Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 9, 2007, 8:51am UTC](https://www.ruby-forum.com/t/2-lines-in-one/88263/1 "2007-03-09T08:51:14Z")

</div>

Could I write it in just 1 line ?

find the first value greater than d, in a list (special one : each  
value is the double of the previous…)  
then give me the index of this value (with special case …)

```
  i =

```

([0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0].select  
{|v| v if v \>= d }).first

```
  zl = d <0.5 ? 0 :

```

[0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0].index(i)

joss

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 9, 2007, 9:15am UTC](https://www.ruby-forum.com/t/2-lines-in-one/88263/2 "2007-03-09T09:15:18Z")

</div>

Alle venerdì 9 marzo 2007, Josselin ha scritto:

> ```
> zl = d <0.5 ? 0 :
> 
> ```
> 
> [0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0].index(  
> i)
> 
> joss

What about this?

a.each\_index{|i| break i if a[i] \> d}

The only problem is that it returns a if no element greater than d is  
found.  
You could turn it into a method, though:

def find\_greater array, value  
array.each\_index{|i| return i if array[i] \> value}  
nil  
end

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 9, 2007, 10:33am UTC](https://www.ruby-forum.com/t/2-lines-in-one/88263/3 "2007-03-09T10:33:28Z")

</div>

2007/3/9, Josselin [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ```
> zl = d <0.5 ? 0 :
> 
> ```
> 
> [0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0].index(i)

irb(main):015:0\>  
arr=[0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0]  
=\> [0.5, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0,  
1024.0, 2048.0]  
irb(main):016:0\> idx = arr.to\_enum(:each\_with\_index).inject(nil)  
{|x,(e,i)| break i if e \> 100}  
=\> 8  
irb(main):017:0\> idx = arr.to\_enum(:each\_with\_index).inject(nil)  
{|x,(e,i)| break i if e \> 1000000}  
=\> nil

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 9, 2007, 10:01am UTC](https://www.ruby-forum.com/t/2-lines-in-one/88263/4 "2007-03-09T10:01:22Z")

</div>

> ```
> zl = d <0.5 ? 0 :
> 
> ```
> 
> [0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0].index(i)

Hi Joss,

In this specific case, you could simply do:

(Math.log(d)/Math.log(2) + 1).ceil

Which is a different kind of solution, and doesn’t need the array.

Cheers,  
Benj

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 9, 2007, 10:11am UTC](https://www.ruby-forum.com/t/2-lines-in-one/88263/5 "2007-03-09T10:11:24Z")

</div>

On Fri, Mar 09, 2007 at 04:50:08PM +0900, Josselin wrote:

> ```
> zl = d <0.5 ? 0 : 
> 
> ```
> 
> [0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0].index(i)

a = [0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0,256.0,512.0,1024.0,2048.0]  
d = 7.0

# version 1: matches your verbal specification

zl = a.each\_with\_index { |v,i| break i if v \> d }

# version 2: matches your sample code’s behaviour

zl = a.each\_with\_index { |v,i| break i if v \>= d }

However this gives different behaviour to your code in the event that d  
is  
greater than the last element in the array (yours returns nil, mine  
returns  
the whole array). Maybe this is OK; you can always stick a 1.0/0.0  
(infinity) at the end of the array. Or:

zl = nil; a.each\_with\_index { |v,i| break zl = i if v \>= d }

But in this particular case you also could use your power-of-two  
property  
and not construct or search an array at all:

zl = d \< 0.5 ? 0 : (d\*2).to\_i.to\_s(2).length

B.

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 9, 2007, 8:55am UTC](https://www.ruby-forum.com/t/2-lines-in-one/88263/6 "2007-03-09T08:55:15Z")

</div>

Hi Joss,

I think you want an alternative to select + index, right?  
I don’t have one so far, but:

arr = [0.5,1.0,2.0,4.0,8.0,16.0,33.0]  
d = 3  
p arr.index(arr.find{|v| v \>= d }) #=\> 3

doesn’t look so bad imo.

You can use Array#each\_with\_index and use an own counter though.

Good luck!
