How do we replace NIL in an array


#1

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


#2

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.


#3

ty vm Ronald! I will definitely try to do it that way. I will write back
with the code when find out how:)


#4

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


#5

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


#6

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


#7

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.


#8

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}

#9

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!!