From: clouder Date: 2007-12-12T05:09:25+09:00 Subject: Re: Find the first non-nil element in an array I had some time wrapping my head around this one messing with irb I was wondering why b.compact! would change the value of a As i continually tried doing a = [1,2,3] b = a b = [1,3,4] and was getting a => [1,2,3] and b => [1,3,4] After trying with strings and gsub and such it finally dinged that b=a has assigned 'b' to the object stored in 'a', so running a method on it was effecting the object stored in both 'a' and 'b'. Where as when I was doing b = [1,3,4] it was creating a new object all together so 'a' was never effected. Is this correct? If so, sorry for making a dumb post if everyone else git this :X I thought I'd post it anyways to possibly help some poor soul like me struggling over why this might not work as expected. On Dec 11, 7:45 am, Phrogz wrote: > On Dec 11, 2:28 am, Stefano Crocco wrote: > > > > > Alle marted́ 11 dicembre 2007, lianliming ha scritto: > > > > Hi all, > > > > Is there any build-in method of class Array which can be used to find > > > the first non-nil element in an array? I can't find any so I am trying > > > to achieve it by my own approach. I don't think my approach is smart > > > enough, so I would like to know better one to do so. Here is what I am > > > doing: > > > > a = [nil, "hello", "world"] > > > b = a > > > b.compact! > > > first_non_nil_elem = b.first > > > > I don't call "compact!" directly on a because it will change a's > > > structure, I want to reserve nil elements in a. > > > > Any suggestions are really appreciated! > > > You can use Enumerable#find, which will return the first item in the array for > > which the block returns true: > > > a = [nil, "hello", "world"] > > puts a.find{|i| !i.nil?} > > => "hello" > > > By the way, you can use compact, instead of compact! to avoid using the > > temporary variable b: > > > a = [nil, "hello", "world"] > > first_non_nil_elem = a.compact.first > > > While compact! removes the nil elements from the receiver, compact returns a > > new array with the nil element removed. > > Moreover, there was no reason to assign to the 'b' variable in the > first place. Doing so doesn't duplicate the array, but just creates > another reference to it. The compact! method still modified the same > array: > > irb(main):006:0> a = [ nil, "foo", "bar" ] > => [nil, "foo", "bar"] > > irb(main):007:0> b = a > => [nil, "foo", "bar"] > > irb(main):008:0> b.compact! > => ["foo", "bar"] > > irb(main):009:0> a > => ["foo", "bar"] > > So if the intent was, as I assume, to preserve the original array with > the nil values, that's even more reason to use #compact instead of > #compact!