Forum: Ruby how do we replace NIL in an array

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
4449200fd21a4e51a285ab7034ab434e?d=identicon&s=25 Yuuji Kazami (overpower)
on 2017-01-31 08:55
Hi.

lets say we have an array and other array

ary = ['a',nil,'c','d']
ary_1 = ['e','f','g','h']

we need to find nil slots first and then fill them with contents of
ary_1

the problem is that there can be 1 nil slot, or 2 nil slots, or 3, or 4

but in this example we need

ary =>['a','e','c','d']
ary_1 => ['f','g','h']

actually the ary_1 is not that important since we can then do

ary_1 = ary_1 - ary

but what i really need is to understand is the first part ..

please help
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2017-01-31 15:39
One simple solution would be to use each_with_index on the first array,
and whenever you find a nil, you replace it with the corresponding
content of the other array.
4449200fd21a4e51a285ab7034ab434e?d=identicon&s=25 Yuuji Kazami (overpower)
on 2017-01-31 17:27
ty vm Ronald! I will definitely try to do it that way. I will write back
with the code when find out how:)
B078cb4f4fb473c7a54d1fc36d10c70e?d=identicon&s=25 Regis d'Aubarede (raubarede)
on 2017-02-02 15:42
Yuuji Kazami wrote in post #1185504:
> Hi.
>
> lets say we have an array and other array
>
> ary = ['a',nil,'c','d']
> ary_1 = ['e','f','g','h']
>
> we need to find nil slots first and then fill them with contents of
> ary_1
>
> the problem is that there can be 1 nil slot, or 2 nil slots, or 3, or 4

 > a=[1,2,3,nil,4,5,nil,nil]
 > b=%w{a b c}
 > v=b.dup
 > a.map {|x| x.nil? ? v.shift : x }
=> [1, 2, 3, "a", 4, 5, "b", "c"]

 > a=[1,2,3,nil,4,5,nil,nil,nil,nil]
 > v=b.dup

 > a.map {|x| x.nil? ? v.shift : x }
=> [1, 2, 3, "a", 4, 5, "b", "c", nil, nil]


So something like that :

def full_up_garbage(hole,garbage)
  v=garbage.dup
  hole.map! { |x|  x.nil? ? v.shift : x }
end
4449200fd21a4e51a285ab7034ab434e?d=identicon&s=25 Yuuji Kazami (overpower)
on 2017-02-04 04:07
Regis d'Aubarede, ty vm for the code. Can you please explain the second
part?

so at first we find a nil { |x| x.nil?} (#i have managed to get to that
myself)

but i do not understand why the second ? and also
v.shift (#we take 'a' from the v array) and then a totaly do not
understand :x

can you please explain this example since its very important for the
beginners and very useful
B078cb4f4fb473c7a54d1fc36d10c70e?d=identicon&s=25 Regis d'Aubarede (raubarede)
on 2017-02-06 12:51
Yuuji Kazami wrote in post #1185525:
> Regis d'Aubarede, ty vm for the code. Can you please explain the second
> part?
>
> so at first we find a nil { |x| x.nil?} (#i have managed to get to that
> myself) but i do not understand why the second ? and also

? is Ruby ternary operator (like in C), in combination with ':' it
designe
a conditional value :

> condition ? value-if-true : value-if false

> true ? 2 : 3
==> 2
> false ? 2 : 3
==> 3

It is a  sugar for a if then else structure:
> if condition then instruction-1 else instrucation-2 end


> v.shift (#we take 'a' from the v array)
shift is Array method which take the first argument of the array, and
supress it of the Array :

> a=[1,2,3]
> a.shift
==> 1
> a
==> [2,3]

"nil?" is a method-name, returning true if object is nil (nil is a
object, and "nil?" is defined in class Object)

object.nil?

> 1.nil?
==> false
> nil.nil?
==> true


a.map {|x| x.nil? ? v.shift : x }

Can be rewrite by :


a.map do |elem|
 if elem.nil?
     ret= b.first
     b=b[1..-1]
 else
   ret = elem
 end
 ret
end
4449200fd21a4e51a285ab7034ab434e?d=identicon&s=25 Yuuji Kazami (overpower)
on 2017-02-06 13:41
thanks!! its clear now. awesome explanation .. now i got to read more
about that ternary operator .. ist basically another short for of if
else ... you have been a great help Regis d'Aubarede.
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2017-02-06 16:27
Regis d'Aubarede wrote in post #1185529:
> a.map {|x| x.nil? ? v.shift : x }
>
> Can be rewrite by :
>
>
> a.map do |elem|
>  if elem.nil?
>      ret= b.first
>      b=b[1..-1]
>  else
>    ret = elem
>  end
>  ret
> end

I think, to make the relationship between ?: and if-then-else even more
clear, it would be better to rewrite

    a.map {|x| x.nil? ? v.shift : x }

as

    a.map {|x|
      if x.nil?
        v.shift
      else
        x
     }

No need to introduce an auxiliary variable here.

BTW, in case we can be sure that x is never false, a more concise way to
write it, would be

    a.map {|x| x||v.shift}
4449200fd21a4e51a285ab7034ab434e?d=identicon&s=25 Yuuji Kazami (overpower)
on 2017-02-07 18:13
i actually did it the way both of you suggested

def put (hole, garbage)

slot = 0
hole.map! {|x| while x.nil?
            x = garbage[slot]
            slot += 1
      end
      x }
 garbage -= hole
 end


ty vm friends!!
This topic is locked and can not be replied to.