2D array assigns input to all inner arrays? [duplicate] - arrays

This question already has an answer here:
Create multiple arrays in one line
(1 answer)
Closed 4 years ago.
I'm trying to get the method input to be stored and outputted like this:
Want [ ["email addresses"], ["phone numbers"], ["names"] ] - > [["bobsmith#example.com","sallyfield#example.com"],["555-555-5555","111-111-1111"],["Bob Smith","Sally Field"]]
This is my code:
def hash_2_array contacts
2 # Extract like info from each hash into arrays
3 stringArr = Array.new(3,Array.new(2)) #=> [ [ nil,nil] , [nil,nil] , [nil,nil] ]
4
5 if contacts.empty?
6 return nonsense = Array.new(3, Array.new)
7 else
8 n=0 #name counter
9 e=0 #email counter
10 p=0 #phone counter
11 contacts.each do |key, value|
12 stringArr[2][n] = key.to_s #adds name to array
13 n+=1
14 value.each do |key2, value2|
15 if key2.to_s.eql?("email")
16 stringArr[0][e] = value2.to_s #adds email address to array
17 e+=1
18 else
19 stringArr[1][p] = value2.to_s #adds phone number to array
20 p+=1
21 end
22 end
23 end
24 end
25 return stringArr
26 end
27
28
29 hash_2_array({:"Bob Smith"=>{:email=>"bobsmith#example.com", :phone=>"555-555-5555"}, :"Sally Field"=>{:email=>"sallyfield#example.com", :phone=>"111-111-1111"}})
It returns:
got: [["555-555-5555", "111-111-1111"], ["555-555-5555", "111-111-1111"], ["555-555-5555", "111-111-1111"]]
It's really confusing why it's not just assigning only the the index in the array that I'm specifying. I think this code worked before, but now it's broken somehow. Any help would be great

From the fine manual:
new(size=0, default=nil)
new(array)
new(size) {|index| block }
[...]
Common gotchas
When sending the second parameter, the same object will be used as the value for all the array elements:
a = Array.new(2, Hash.new)
# => [{}, {}]
a[0]['cat'] = 'feline'
a # => [{"cat"=>"feline"}, {"cat"=>"feline"}]
a[1]['cat'] = 'Felix'
a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}]
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:
a = Array.new(2) { Hash.new }
a[0]['cat'] = 'feline'
a # => [{"cat"=>"feline"}, {}]
When you say this:
stringArr = Array.new(3,Array.new(2))
You're creating an array with three elements but all those elements are exactly the same array. You want an array that contains three different arrays as elements:
stringArr = Array.new(3) { Array.new(2) }

Related

Ruby: NoMethodError when comparing element in an array

I'm working on a method that takes an array of words as a param and returns an array of arrays, where each subarray contains words that are anagrams of each other. The line while sort_array[i][1]==temp do is throwing undefined method '[]' for nil:NilClass (NoMethodError) and I have no idea why.
def combine_anagrams(words)
sort_array = Hash.new
words.each do |w|
sort_array[w] = w.split("").sort
end
sort_array = sort_array.sort_by { |w, s| s }
return_array = []
i = 0
while i<sort_array.length do
temp_array = []
temp = sort_array[i][1]
while sort_array[i][1]==temp do
temp_array += [sort_array[i][0]]
i+=1
end
return_array += [temp_array]
end
return temp_array
end
p combine_anagrams( ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams','scream'] )
It looks like this is because you are incrementing your i variable without checking to make sure you're still in bounds of the sort_array. To see the problem, put an puts statement in your code inside the inner most while loop:
while sort_array[i][1]==temp do
temp_array += [sort_array[i][0]]
i+=1
puts "i is #{i} and the length is #{sort_array.length}"
end
and then run your code and you'll see:
i is 1 and the length is 8
i is 2 and the length is 8
i is 3 and the length is 8
i is 4 and the length is 8
i is 5 and the length is 8
i is 6 and the length is 8
i is 7 and the length is 8
i is 8 and the length is 8
example.rb:15:in `combine_anagrams': undefined method `[]' for nil:NilClass (NoMethodError)
You need to make sure on both while loops that you stay within the bounds of your array, for instance:
while i < sort_array.length && sort_array[i][1]==temp do
end
As a side note, your code is currently only going to return the last temp_array, since you're also resetting that at the beginning of your outer while loop. And, if I understand what problem you're trying to solve you might want to look at group_by available on Array thanks to the Enumerable module:
words = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams','scream']
words.group_by { |word| word.chars.sort }.values
# => [["cars", "racs", "scar"], ["for"], ["potatoes"], ["four"], ["creams", "scream"]]

How to set array starting and end indices in swift?

I tried to create an array from 1-100 elements create in playground, but while i'm trying to print it doesn't print the values in the array.
code:
var ab:Array = [1...100]
for i in ab {
print(i)
}
output:
But in the playground it didn't shown any error.
Did i do anything wrong?
Thanks
You create an array of Range<Int> elements (a single one, 1..<101)
var ab: Array = [1...100] // element TYPE inferred from 1...100
// to be Range<Int>
print(ab.dynamicType)
// Array<Range<Int>>
But I assume you're attempting to create an array of 100 Int elements.
var ab = Array(1...100) // Array with elements intialized to Int,
// using Range<Int> to intialize
for i in ab {
print(i)
} // 1 2 3 ... 100
If you're only looking to print the numbers in the range 1...100, you needn't necessarily create an array if integers to do so (or an array at all). Instead, you could use a single Range<Int> variable and loop over the elements contained in this range. E.g.
let myRange = 1...5 // inferred as type Range<Int>
for i in myRange {
print(i) // the type of 'i' is Int, the same as in
// the array case above.
} // 1 2 3 4 5
Use clear and effective ;
var ab = Array(1...100)
for i in ab {
print(i)
}
Output
1 2 3.... 100

Adding an element of an array with respective element of other arrays

I have multiple array, number can be arbitrary. but the size of all array is same. How do i add each element of with respective element of all the arrays and maybe save it in another array
A1 = [1 2 3 4 5 6]
A2 = [1 2 3 4 5 6]
.
.
.
.
final = [1+1+1+... 2+2+2+.... 3+3+3+3.... 4+4+4.... 5+5+5+5... 6+6+6+6...]
As your arrays are all the same length you can just add the arrays forming a new array.
final = A1+A2
This function searches in your workspace looking for all variables containing capital 'A'. The for loop adds all found variables. If there are other variables containing 'A', other restrictions has to be made.
variables = who %# all variable names from workspace
index = strmatch('A',variables) %# indices matching "A"
newarray = 0
for j = 1:numel(index)
tmp = eval(char(variables(index(j)))); %# store variable in tmp
newarray = newarray + tmp; %# sum
end
If you have an unknown number of A's, you can try something like this:
final = 0
i = 1
while exist(['A' num2str(i)]) == 1 % ['A' num2str(i)] constructs the variable name, eval calls it
final = final + eval(['A' num2str(i)]);
i = i + 1;
end
This should work as long as the variables are stored in the workspace, are of the same length and are named A1, A2, A3, ... A9, A10, ...
Let's say you have this structure (as you write in the comments):
main = struct('err',{1:6,5:10,1:6,1:6},'seg_err',{1:6,5:10,1:6,5:10});
you can convert it to matrix:
m = vertcat(main.seg_err);;
And than take the sum in a simple command:
final = sum(m)
which results:
final =
12 16 20 24 28 32
and thanks to #beaker :)

sorting dynamic multidimensional array

im tryin to sort a two-dimensional Array in Ruby by the first value, like that:
files_array = Array.new(2) {Array.new}
files_array[0][0] = 42
files_array[1][0] = "/media/js/aefc015sdfsdf0728175535.js42"
files_array[0][1] = 21
files_array[1][1] = "/media/js/aefc015sdfsdf0728175535.js21"
files_array[0][2] = 30
files_array[1][2] = "/media/js/aefc015sdfsdf0728175535.js30"
i tried
files_array.sort!{|a,b| b[0] <=> a[0]}
but it returns:
`sort!': comparison of Array with Array failed (ArgumentError)
This is how i want the array to be sorted:
files_array[0][0] = 21
files_array[1][0] = "/media/js/aefc015sdfsdf0728175535.js21"
files_array[0][1] = 30
files_array[1][1] = "/media/js/aefc015sdfsdf0728175535.js30"
files_array[0][2] = 42
files_array[1][2] = "/media/js/aefc015sdfsdf0728175535.js42"
`sort!': comparison of Array with Array failed (ArgumentError)
This is because a[0] and b[0] are elements of an array of arrays, i.e. they are arrays themselves.
If you did this:
files_array.sort!{|a,b| b[0][0] <=> a[0][0]}
It would work.
Incidentally, this looks like a great example of when an associative array would be a better idea than an array of arrays.
files_hash = {
42 => "/media/js/aefc015sdfsdf0728175535.js42",
21 => "/media/js/aefc015sdfsdf0728175535.js21",
30 => "/media/js/aefc015sdfsdf0728175535.js30"
}
Not only is this a lot clearer in code, but you do away with the need to maintain a sorted 2-dimensional array.
try this it will work for you:
files_array = [[42,"/media/js/aefc015sdfsdf0728175535.js42"],[21,"/media/js/aefc015sdfsdf0728175535.js21"],[30,"/media/js/aefc015sdfsdf0728175535.js30"]]
sorted = files_array.sort { |x,y| x[0] <=> y[0] }
puts sorted
Result:
21
/media/js/aefc015sdfsdf0728175535.js21
30
/media/js/aefc015sdfsdf0728175535.js30
42
/media/js/aefc015sdfsdf0728175535.js42

Nodejs: How to loop through an associative array

So let's say I have an array with a bunch of values say
"abc" = 5
"bcd" = 12
"ddd" = 13
I would like to be able to loop through and print all these out in a format similar to
abc: 5
bcd: 12
ddd: 13
If there is an assoc. array that's quite large and I don't know all the keys. How do I print out all of the keys and values?
Thanks
Try this:
for(var prop in obj) {
if(obj.hasOwnProperty(prop)){
console.log(prop + ': ' + obj[prop]);
}
}

Resources