Response list returns empty nested array: [[], [], []]
How better test with ruby that following nested array is empty?
You can use Array#empty?
To check all nested arrays are empty with Array#all?
[[], [], []].all?(&:empty?)
# => true
[[1], [2], []].all?(&:empty?)
# => false
[[1], [2], [3]].all?(&:empty?)
# => false
To check at least one nested is empty with Array#any?
[[], [], []].any?(&:empty?)
# => true
[[1], [2], []].any?(&:empty?)
# => true
[[1], [2], [3]].any?(&:empty?)
# => false
If you want to handle deeply nested arrays, you probably want to flatten your array first:
[[], [], []].flatten.empty?
=> true
[[], [[], [[]]]].flatten.empty?
=> true
[[], [[], [[1]]]].flatten.empty?
=> false
Related
I have the following array:
#master = Array.new(4, Array.new(2, Array.new()))
=> [[[], []], [[], []], [[], []], [[], []]]
I'm attempting to assign the very first most value with:
#master[0][0] = "x"
=> "x"
But this is doing a multi assignment
#master
=> [["x", []], ["x", []], ["x", []], ["x", []]]
How do I assign only the first value? I'm hoping to get the following Array:
#master
=> [["x", []], [[], []], [[], []], [[], []]]
In that way you use the same reference for every sub array. Try this way
#master = Array.new(4) { Array.new(2) { Array.new } }
You are creating one array an assigning it to every element of the first array; try running this code:
#master.each { |e| puts e.object_id }
Output (your ids will be different):
70192803217260
70192803217260
70192803217260
70192803217260
As you can see, is the exact same object, so try using #master = Array.new(4) { Array.new(2) { Array.new() } } instead, which will create a new array for each item in the first array.
I tried to create a nested array, but when I update one of them, all other arrays seems to be updated, What am I doing wrong?
arr = Array.new(5,Array.new())
# => [[], [], [], [], []]
arr[0]
# => []
arr[0].push(1)
# => [1]
arr
# => [[1], [1], [1], [1], [1]]
You could use the block syntax to initialize the array:
arr = Array.new(5) { Array.new }
=> [[], [], [], [], []]
arr[0].push(1)
arr
=> [[1], [], [], [], []]
map produces the array:
arr = 5.times.map { [] }
arr.first << 42
#⇒ [42]
arr
#⇒ [[42], [], [], [], []]
This question already has answers here:
Why does array.each behavior depend on Array.new syntax?
(3 answers)
Closed 5 years ago.
Can anyone explain this to me:
irb(main):001:0> a = Array.new(3, [])
=> [[], [], []]
irb(main):001:0> b = [[], [], []]
=> [[], [], []]
irb(main):003:0> a.each_with_index{ |r, idx| r << 'a' }
=> [["a", "a", "a"], ["a", "a", "a"], ["a", "a", "a"]]
irb(main):004:0> b.each_with_index{ |r, idx| r << 'a' }
=> [["a"], ["a"], ["a"]]
When using the .new method:
Since all the Array elements store the same hash, changes to one of them will affect them all.
If multiple copies are what you want, you should use the block version which uses the result of that block each time an element of the array needs to be initialized:
2.3.0 :001 > a = Array.new(3) { [] }
=> [[], [], []]
2.3.0 :002 > a.each_with_index{ |r, idx| r << 'a' }
=> [["a"], ["a"], ["a"]]
Read the examples here - https://ruby-doc.org/core-2.2.0/Array.html#method-c-new
How would I write this java code into ruby:
String[] [] Score = new String [row] [col];
Score[rCount][cCount] = num;
I thought it would as simple as:
score=[]
score[rcount][ccount]=num
But I keep getting "undefined method `[]=' for nil:NilClass (NoMethodError)"
Sorry, I don't know java, but have a look at the class methods Array#new and Array::[], and the instance methods Array#[]= and Array#[]. Here are some examples that should answer your question (and other questions that may be sparked, hopefully):
Array.new #=> []
[] #=> [] # shorthand for above
a = Array.new(5) { [] } #=> [[], [], [], [], []]
a[0][0] = 2
a #=> [[2], [], [], [], []]
a[3][2] = 4
a #=> [[2], [], [], [nil, nil, 4], []]
a[1] << 1
a #=> [[2], [1], [], [nil, nil, 4], []]
a[1] << 2
a #=> [[2], [1, 2], [], [nil, nil, 4], []]
a[1] << 3 << 4
a #=> [[2], [1, 2, 3, 4], [], [nil, nil, 4], []]
a[2] << [4,5]
a #=> [[2], [1, 2, 3, 4], [[4, 5]], [nil, nil, 4], []]
a[4].concat([4,5])
a #=> [[2], [1, 2, 3, 4], [[4, 5]], [nil, nil, 4], [4, 5]]
a = Array.new(3) { Array.new(3) }
#=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
a[1][2] = 4
a #=> [[nil, nil, nil], [nil, nil, 4], [nil, nil, nil]]
We could also write the default as a second argument:
a = Array.new(3,[]) #=> [[], [], []]
but that can be problematic:
a[0][0] = 'cat'
a #=> [["cat"], ["cat"], ["cat"]]
as is:
a = Array.new(3,Array.new(2)) #=> [[], [], []]
#=> [[nil, nil], [nil, nil], [nil, nil]]
a[0][0] = 'cat'
a #=> [["cat", nil], ["cat", nil], ["cat", nil]]
since each element of a is the same array.
Note that Ruby provides a convenience for writing certain methods that is commonly referred to as "syntactic sugar". If, for example, you write a = [1,2,3], Ruby will interpret that as a = Array.[](1,2,3) (and you could write it that way), the class method being Array::[]. Similarly, if a equals [1,2,3], a[1] = 'cat' is decoded as a.[]=(1, 'cat') and a[1] #=> 'cat' is a.[](1). Similarly, h = {} translates to h = Hash.new and so on.
Note that Ruby does not have a concept of "multidimensional arrays". For more on that you may wish to see a comment a left on this question.
Firstly, ruby programmers use snake case. Capital letter is using for class names.
Secondly, your problem happens just because
score[rcount] == nil # true
If you want to have an access to second dimension elements you need to initialize line as array:
score[rcount] = []
Now you can set second dimension element
score[rcount][ccount] = num
Recently I attempted to append a number to one of the nested arrays in my script.
I expected only the nested array at the specified index to have the number appended to it, but what actually happened was that all of the nested arrays had the number appended to them.
This behaviour seems very odd, why do ruby arrays function this way?
irb(main):001:0> [1,2,3].push 3
=> [1, 2, 3, 3]
irb(main):002:0> layered = [[]] * 5
=> [[], [], [], [], []]
irb(main):003:0> layered[0] << 2
=> [2]
irb(main):004:0> layered
=> [[2], [2], [2], [2], [2]]
irb(main):005:0>
Because all of them are the same array. You can check it by calling Object#object_id on each element:
[3] pry(main)> layered = [[]] * 5
=> [[], [], [], [], []]
[4] pry(main)> layered[0].object_id
=> 70207042910540
[5] pry(main)> layered[1].object_id
=> 70207042910540
[6] pry(main)> layered[2].object_id
=> 70207042910540
To create new array for each element then use Array.new(5) { [] }.