Astro Lee Astro Lee - 4 months ago 18
Javascript Question

Translating JavaScript into Ruby, for splitting Excel data into two dimensional variables

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();
var rows = data.split("\n");
var l = rows.length - 3;
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];
} //data generate

This is my attempt in Ruby:

data = @bindo.bindo_input
rows = data.split("\n")
length = rows.length - 3
@datas =
cells = { }
rows.length.each do |y|
cells << rows[y].split("\t")
@datas[y] =
cells.length.each do |x|
@datas[y][x] = cells[x]

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.


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 do |i|

Another note about your code: you are using to build arrays which is fine, though you could simply use [] as well. The brackets in cells = {} aren't doing anything. It is possible to pass a block to the constructor, but you don't seem to be using it for the correct purpose. See Ruby array creation, 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]