How can I generate new variables?

Hello, this is not so much a sketchup question as a Ruby one that I
cannot figure out. What I am trying to do is create new variables that
all have the same base name then add a number to make a series of
variables named like wall1, wall2, wall3, ect.

What I am trying to do is take an array, lets call it originalarray,
which has say 64 objects in it, and create 8 smaller arrays from this.
So array1 would be orginalarray[0-7], array2 would be
originalarray[8-15], and so on for 8 new arrays. The problem is I do not
know the length of the original array, as it is being populated by data
from an xml sheet, but I know the multiple of how it is being created,
ie by multiples of 8.

I have been trying to do this using loops doing something like:

n=0
while n != originalarray.length/8
  n=n.to_s
  array+n=originalarray[0..7]
  n=n.to_i
  n=n+1
end

I realize that is doesn’t work at all in that you cannot make variables
like this, I am just trying to give a better picture of what my goal is.
So I am wondering is it possible to accomplish this at all, and if so
how? Or is there a much easier way to do this using classes or some
other method to accomplish the same goal?

Any help would be greatly appreciated. Thank you in advance for your
time.

Kyle X. wrote in post #990090:

Hello, this is not so much a sketchup question as a Ruby one that I
cannot figure out. What I am trying to do is create new variables that
all have the same base name then add a number to make a series of
variables named like wall1, wall2, wall3, ect.

You mean like wall[1], wall[2], wall[3], etc.?

What I am trying to do is take an array, lets call it originalarray,
which has say 64 objects in it, and create 8 smaller arrays from this.
So array1 would be orginalarray[0-7], array2 would be
originalarray[8-15], and so on for 8 new arrays. The problem is I do not
know the length of the original array, as it is being populated by data
from an xml sheet, but I know the multiple of how it is being created,
ie by multiples of 8.

I have been trying to do this using loops doing something like:

n=0
while n != originalarray.length/8
  n=n.to_s
  array+n=originalarray[0..7]
  n=n.to_i
  n=n+1
end

I realize that is doesn’t work at all in that you cannot make variables
like this, I am just trying to give a better picture of what my goal is.
So I am wondering is it possible to accomplish this at all, and if so
how?

Using arrays. An array can contain anything–including other arrays:

require ‘enumerator’ #not necessary in ruby 1.9

master_arr = []
data = [1, 2, 3, 4, 5, 6, 7, 8]

data.each_slice(3) do |triplet|
master_arr << triplet
end

p master_arr

–output:–
[[1, 2, 3], [4, 5, 6], [7, 8]]

The names of the arrays are:

master_arr[0]
master_arr[1]
master_arr[2]

Voila! But in ruby, you rarely need to refer to index positions in an
array because you can do this:

master_arr.each do |arr|
p arr
end

–output:–
[1, 2, 3]
[4, 5, 6]
[7, 8]

Or this:

master_arr.each do |arr|
new_arr = arr.map do |element|
element * 2
end

p new_arr
end

–output:–
[2, 4, 6]
[8, 10, 12]
[14, 16]

First off thank you for the reply, and as you can probably tell I am
very novice at ruby ><. However I am running into a few issues with
this.

Using arrays. An array can contain anything–including other arrays:

require ‘enumerator’ #not necessary in ruby 1.9

master_arr = []
data = [1, 2, 3, 4, 5, 6, 7, 8]

data.each_slice(3) do |triplet|
master_arr << triplet
end

p master_arr

–output:–
[[1, 2, 3], [4, 5, 6], [7, 8]]

I am writing this for SketchUP so I am using Ruby 1.8.6 and am having an
issue with require ‘enumerator’, as it does not exist in their library
as far as I can tell — in turn the “each_slice” command does not
function.

I was wondering if you could help me understand this command better as
well. “data.each_slice(3) do |triplet|” The “(3)” here means slice
after 3 entries in data correct? The word triplet used, is this word
required or could it be any word as long as it is consistent below i.e.
: do |x| master_arr << x? Sorry for the basic question, but I just
want to clarify.

The names of the arrays are:

master_arr[0]
master_arr[1]
master_arr[2]

Voila! But in ruby, you rarely need to refer to index positions in an
array because you can do this:

master_arr.each do |arr|
p arr
end

–output:–
[1, 2, 3]
[4, 5, 6]
[7, 8]

Or this:

master_arr.each do |arr|
new_arr = arr.map do |element|
element * 2
end

p new_arr
end

–output:–
[2, 4, 6]
[8, 10, 12]
[14, 16]

The rest I think I have figured out, but still not 100% on the map
function.

Thank you again for your time.

On Thu, Mar 31, 2011 at 5:08 AM, Kyle X. [email protected] wrote:

data = [1, 2, 3, 4, 5, 6, 7, 8]
I am writing this for SketchUP so I am using Ruby 1.8.6 and am having an
issue with require ‘enumerator’, as it does not exist in their library
as far as I can tell — in turn the “each_slice” command does not
function.

You can easily cook it yourself

module Enumerable
def each_slice(n)
a = []

each do |x|
  a << x

  if a.size == n
    yield a
    a.clear
  end
end

yield a unless a.empty?
self

end
end

I was wondering if you could help me understand this command better as
well. “data.each_slice(3) do |triplet|” The “(3)” here means slice
after 3 entries in data correct?

Correct.

The word triplet used, is this word
required or could it be any word as long as it is consistent below i.e.
: do |x| master_arr << x? Sorry for the basic question, but I just
want to clarify.

Yes, it’s the name of the block argument. You can name it anyway you
like. You should only avoid reusing a name used outside the block in
order to avoid confusion and incompatibility should the program be
executed on 1.9 at one day.

You can even use three names!

irb(main):041:0> Array.new(10) {|idx| idx}
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):042:0> Array.new(10) {|idx| idx}.each_slice(3)
{|first,second,third| p first}
0
3
6
9
=> nil

The rest I think I have figured out, but still not 100% on the map
function.

Enumerable#map sends all values through a conversion function and
collects them in a new Array:

irb(main):043:0> Array.new(10) {|idx| idx}.map {|x| x + 100}
=> [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]

Kind regards

robert

Thank you all very much for your responses. Both solutions work great.
Thanks again.

2011/3/31 Kyle X. [email protected]

I am writing this for SketchUP so I am using Ruby 1.8.6 and am having an
issue with require ‘enumerator’, as it does not exist in their library
as far as I can tell — in turn the “each_slice” command does not
function.

Then you must write your own version. For example
def slice(array, chunk_size)
result = []
array.each_with_index do |element, index|
result << [] if index % chunk_size == 0
result.last << element
end

result
end

arr = [1,2,3,4,5,6]
slice(arr,2) #=> [[1,2],[3,4],[5,6]]

I was wondering if you could help me understand this command better as

well. “data.each_slice(3) do |triplet|” The “(3)” here means slice
after 3 entries in data correct? The word triplet used, is this word
required or could it be any word as long as it is consistent below i.e.
: do |x| master_arr << x? Sorry for the basic question, but I just
want to clarify.

Your right. You can call the thing triplet, x or chunky_bacon. Its just a
name for a local variable.

Kyle X. wrote in post #990113:

First off thank you for the reply, and as you can probably tell I am
very novice at ruby >

No problem–that’s what this forum is for.

require ‘enumerator’ #not necessary in ruby 1.9

master_arr = []
data = [1, 2, 3, 4, 5, 6, 7, 8]

data.each_slice(3) do |triplet|
master_arr << triplet
end

p master_arr

–output:–
[[1, 2, 3], [4, 5, 6], [7, 8]]

I am writing this for SketchUP so I am using Ruby 1.8.6 and am having an
issue with require ‘enumerator’, as it does not exist in their library
as far as I can tell

I’m using ruby 1.8.6 too, and the enumerator module is part of the ruby
standard library. Are you sure you spelled it right? But if it’s not
provided, it’s not provided.

I was wondering if you could help me understand this command better as
well. “data.each_slice(3) do |triplet|” The “(3)” here means slice
after 3 entries in data correct?

Yes, the each_slice() method allows you to chop up an array into chunks
of the specified size. Perhaps the simplest way to accomplish the same
thing in ruby 1.8.6 is using slice():

arr = [10, 20, 30, 40, 50]
results = []

while arr.size > 0
results << arr.slice!(0, 3) #(start_index, length)
end

p results

–output:–
[[10, 20, 30], [40, 50]]

The word triplet used, is this word
required or could it be any word as long as it is consistent below i.e.
: do |x| master_arr << x? Sorry for the basic question, but I just
want to clarify.

‘triplet’ is just a descriptive variable name. It is a “block
parameter” which is just like a method parameter:

def do_stuff(x) #x is a method parameter
x+2 #or you can explicitly write: return x+2
end

answer = do_stuff(5)
puts answer #=> 7

Ruby uses blocks everywhere. Here is a simple example:

words = [“hello”, “world”, “goodbye”]

words.each do |word|
puts word + “.”
end

–output:–
hello.
world.
goodbye.

The each() method sends each element of the array to the block, which is
this part:

  do |word|

puts word
end

‘do’ signals the start of a block. What happens is that ruby calls the
block, which is like a method, for each element of the array. In
my example, the element of the array is assigned to the variable named
‘word’, and then inside the block you can do whatever you want to the
word variable.

The map() function, like each(), tells ruby to send each element of the
array to the block. However, map() also takes the return value of the
block
and shoves it into a new array:

words = [“hello”, “world”, “goodbye”]

new_arr = words.map do |x|
1
end

p new_arr

–output:–
[1, 1, 1]

In that example, the block returns 1 for every element of the array.
But you can use map to do more useful things–like capitalize all the
words in the array:

words = [“hello”, “world”, “goodbye”]

new_arr = words.map do |x|
x.capitalize #same as: ‘return x.capitalize’
end

p new_arr

–output:–
[“Hello”, “World”, “Goodbye”]

So whenever, you want to do something to every member of an array and
save the results in a new_array, map()is a good choice.

Dear 7stud,

Thank you for the very clear descriptions. Your examples are much more
helpful than the examples I find in places like -
http://www.germane-software.com/software/rexml/doc/index.html

On Sat, Apr 2, 2011 at 8:18 AM, Kyle X. [email protected] wrote:

Dear 7stud,

Thank you for the very clear descriptions. Your examples are much more
helpful than the examples I find in places like -
http://www.germane-software.com/software/rexml/doc/index.html

But that is about REXML and not general iteration of collections in
Ruby. For REXML: did you look at the tutorial?
http://www.germane-software.com/software/rexml/docs/tutorial.html

Cheers

robert

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs