Astro Lee - 4 months ago 18

Javascript Question

Below is JavaScript for splitting copy & pasted Excel data. My purpose is to split given Excel data into each unit cell, and reuse them in the HTML side. My problem is that I was able to write it in Javascript, but I'm having trouble rewriting it in Ruby. I need some help here.

Here is my JavaScript:

`var data = $('textarea[name=excel_data]').val();`

console.log(data);

var rows = data.split("\n");

var l = rows.length - 3;

console.log(l);

var table = $('<table class="table table-bordered" />');

var datas = new Array();

for(var y in rows) {

var cells = rows[y].split("\t");

var row = $('<tr />');

datas[y] = new Array();

for(var x in cells) {

row.append('<td id='+y+x+'>'+cells[x]+'</td>');

datas[y][x] = cells[x];

$('#excel_table_a'+l+'_'+y+x).html(datas[y][x]);

$('#excel_table_b'+l+'_'+y+x).html(datas[y][x]);

$('#excel_table_c'+l+'_'+y+x).html(datas[y][x]);

$('#excel_table_d'+l+'_'+y+x).html(datas[y][x]);

$('#excel_table_e'+l+'_'+y+x).html(datas[y][x]);

$('#excel_table_z'+l+'_'+y+x).html(datas[y][x]);

} //data generate

table.append(row);

}

This is my attempt in Ruby:

`data = @bindo.bindo_input`

rows = data.split("\n")

length = rows.length - 3

@datas = Array.new

cells = Array.new { }

rows.length.each do |y|

cells << rows[y].split("\t")

@datas[y] = Array.new

cells.length.each do |x|

@datas[y][x] = cells[x]

end

end

When I try to run this code on Rails, I get an error message like this:

undefined method `each' for 7:Fixnum

I would really appreciate you, for any help.

Answer

`rows.length`

returns a number.

`each`

is a method defined on Range, Enumerable, Hash, and Array (and maybe others, but not integer).

What you're trying to do (iterate `rows.length`

times) can be accomplished with any of the following:

```
# Enumerator#times
rows.length.times do |i|
# Enumerator#times + each
rows.length.times.each do |i|
# Range#each
0.upto(rows.length - 1).each do |i|
# another Range#each
(0..(rows.length - 1)).each do |i|
# Array#each
Array.new(rows.length).each do |i|
```

Another note about your code: you are using `Array.new`

to build arrays which is fine, though you could simply use `[]`

as well. The brackets in `cells = Array.new {}`

aren't doing anything. It is possible to pass a block to the `Array.new`

constructor, but you don't seem to be using it for the correct purpose. See Ruby array creation, Array.new vs []

Also, doing a little refactor:

```
rows = @bindo.bindo_input.split("\n")
corrected_rows_length = rows.length - 3
@datas = []
cells = []
corrected_rows_length.times do |y|
cells << rows[y].split("\t")
@datas[y] = []
cells.length.times do |x|
@datas[y][x] = cells[x]
end
end
```