I have an array, and want to copy it so I can check if it has changed.
The array looks like this:
#table = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
and I copy the values like this:
#old_table = #table.clone
I have two sorting methods, one that sorts it hortizontaly and the other sorts it vertically.
Everything works fine with the horizontal method but when I use the vertical routine, it changes the value of #old_table to the cloned array.
I already checked the object id and it's not the same. I tried with other ways to copy the value too but I get the same result.
Horizontal:
currline = 0
4.times do
#line = #table[currline].clone.reverse
compare
sort
#table[currline] = #line.reverse
currline += 1
end
Vertical:
currline = 0
4.times do
#line = [#table[0][currline],#table[1][currline],#table[2][currline],#table[3][currline]].reverse
compare
sort
#line.reverse!
#table[0][currline] = #line[0]
#table[1][currline] = #line[1]
#table[2][currline] = #line[2]
#table[3][currline] = #line[3]
currline += 1
end
Here's a link to the whole code: http://pastebin.com/1xzLx5ib
I need help to figure out why the vertical method changes the value of #old_table to the original when it shouldn't.
It's because the outer array is cloned, but not the 4 inner arrays.
#table = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
#old_table = #table.clone
#old_table.object_id
# => 70198498995020
#table.object_id
# => 70198498975440 (So far so good)
#old_table[0].object_id
# => 70198498975520
#table[0].object_id
# => 70198498975520 (Same row id!)
One simple way to fix this is to serialize and unserialize the array:
#old_table = Marshal.load Marshal.dump(#table)
Related
I'm trying to generate a table while changing the background color of a cell under a condition. I've resorted coming to here for help. Here's an example of what I'm trying to do:
idx = 0
pdf.table(myTable) do
style(row(0), :background_color => 'ff00ff')
style(column(0))
while idx <= totalRows
if cells[idx,3] == "No go"
style(cells[idx,3], :background_color => 'fF0000')
else
style(cells[idx,3], :background_color => '00FF22')
end
idx += 1
end
end
Call #style correctly
In version 0.2.2 of prawn-table, the #style method is defined on a cell, or an array of cells, so you need to get that first. The argument is merely a hash of the keys and values for the styles you want. For example, row(0) is an array of cells, so you can style it with a magenta background like this:
pdf.table(myTable) do
row(0).style(:background_color => 'ff00ff')
end
You can refer to the full source code of #style at
https://github.com/prawnpdf/prawn-table/blob/0.2.2/lib/prawn/table/cells.rb#L139 and
https://github.com/prawnpdf/prawn-table/blob/0.2.2/lib/prawn/table/cell.rb#L227
column(0)
I am not sure what you want the line style(column(0)) to do, so I can't advise on that.
Condition when "No go"
It looks like you want the while loop to apply a condition to the fourth column, so that cells whose content is 'No go' are red, while the rest are green.
For this, you can use the iterator built-in to the #style method, instead of your while loop. It could look like this:
column(3).style do |cell|
if cell.content == "No go"
cell.style(:background_color => 'ff0000')
else
cell.style(:background_color => '00ff22')
end
end
If you wanted something slightly different you should know enough now to vary the code.
What I'm trying to do is giving a list of columns, get an array of column formats. I have an array of column names, and a has where the key is the column name and the value is the format the column needs. If there's no value in the hash for a given column, it needs to be nil in the resulting array.
Given:
report_columns = ["val1", "val2", "subtotal",
"othertotal", "grand_total", "moar_total"]
column_formats = {"grand_total" => #highlight_money,
"subtotal" => #money}
I can easily do it with this code:
datatype_array = []
report_columns.each {|col| datatype_array << column_formats[col] }
# do stuff with datatype_array
But this is ruby. There's a more concise way to do this! Please let me know what magic method I'm missing.
You're first attempt should be a simple map rather than an each that accumulates onto an array.
datatype_array = report_columns.map { |c| column_formats[c] }
You can also splat the array of columns into Hash#values_at, which expects multiple key names as individual arguments:
datatype_array = column_formats.values_at(*report_columns)
I have some arrays that I put into one array called alist[]. I am iterating over the array to print out all values of alist[]. I need to find a value at alist[2][i] and then remove the alist[0][i], alist[1][i], alist[2][i], alist[3][i], alist[4][i] from my array alist[][]. (I removed the code that fills my arrays so it is easier to read my question)
This is my best guess below but it is not working. Would anyone have any ideas?
#declare arrays
nsymbol = []
sname = []
etf = []
testv = []
financials = []
alist = []
#create one array with all other arrays
alist.push(nsymbol, sname, etf, testv, financials)
(0...nsymbol.length).each do |i|
(0...alist.length).each do |j|
if (alist[2][i] || '').include? 'Y'
alist.delete_at(0)
alist.delete_at(1)
alist.delete_at(2)
alist.delete_at(3)
alist.delete_at(4)
end
#print whole array out
puts alist[j][i]
end
end
By performing alist.delete_at(0) you delete the first item of alist so to speak alist[0][0..N] but you want to delete alist[0][i] so you need to delete the ith item of alist[0].
alist[0].delete_at(i)
alist[1].delete_at(i)
# etc.
Because you are printing your array just after deleting the new contents it doesn't matter, but if you want to use the array after this you should break the loop after deleting the entries, because deleting the entries leads to another entry now being the item alist[2][i] and eventually to a further deletion of the entries. (Though this might also be exactly what you want).
I have a array of n elements say
snaps = ["s-1","s-2","s-3","s-4",..."s-n-2","s-n-1","s-n"]
now I want to create two diff array such that one array contains last 5 elements and another contains remaining elements.For example
snap1 = ["s-1","s-2","s-3","s-4",...]
snap2 = ["s-n-5","s-n-3","s-n-2","s-n-1","s-n"]
How can I do this.
snap1 = snaps.dup
snap2 = snap1.pop(5)
snap2 = snaps[-5, 5]
Or
snap2 = snaps.last(5) # As suggested my BroiSatse
will give you an array with the last 5 elements
For the remaining, you can do
snap1 = snaps[0..-6]
You can use slice! to create the two arrays:
snaps = ["s-1","s-2","s-3","s-4","s-n-5","s-n-3","s-n-2","s-n-1","s-n"]
snap2 = snaps.slice!(-5..-1)
# => ["s-n-5", "s-n-3", "s-n-2", "s-n-1", "s-n"]
snaps
# => ["s-1", "s-2", "s-3", "s-4"]
The following code demonstrates a ruby (1.8.7) for loop in which a column and header read in from excel are saved as an object (object attributes: header=string, contents=array of strings). As I'm reading in several columns I want to save them as an array of objects.
The issue is that each loop, while incrementing the array 'matrix', and successfully storing the new object, seems to overwrite the previous elements of the matrix array with the newest object. When I iterate through the finished array, I just get x instances of the same object.
column_count = count_columns(worksheet)
row_count = count_rows(worksheet)
matrix = Array.new
#i don't think header needs to be an array in the below loop, but anyway...
header = Array.new
contents = Array.new
for column in 0..column_count - 1
header[column] = worksheet.Cells(1, column + 2).Value
for row in 0..row_count
contents[row] = worksheet.Cells(row + 2, column + 2).Value
end
matrix[column] = Worksheet_Column.new(header[column], contents)
end
#looping after the array was created puts the same information in each iteration
for column in 0..matrix.length - 1
puts "loop = #{column}"
puts matrix[column]
end
Well, I still don't see what elementary mistake allowed the contents to write backward, but having noticed the problem occurred for the contents and not for the header this solution has been successful.
for column in 0..column_count - 1
contents[column] = Array.new
header[column] = worksheet.Cells(1, column + 2).Value
for row in 0..row_count
contents[column][row] = worksheet.Cells(row + 2, column + 2).Value
end
matrix[column] = Worksheet_Column.new(header[column], contents[column])
end