Potential methods of combining 2 arrays into a single concatenated array string (TOPIC TITLE EDITED)

Hello everyone. :grinning:

I want to connect the text of 2 arrays.

For everyone to understand, here is an example:

   array1 = ['1-','2-','3-']
   array2 = ['FIRST','SECOND','THIRD']

I want to get this out:

   '1-FIRST'
   '2-SECOND'
   '3-THIRD'

I have tried many things with “each”, “&”, “+”, " << "… but I can not find a solution.

Thank you in advance for your help.

David

I found this:

   array1 = ['1-','2-','3-']
   array2 = ['FIRST','SECOND','THIRD']
   
   puts array1[0] + array2[0]
   puts array1[1] + array2[1]
   puts array1[2] + array2[2]

But it’s not appropriate because the list can be long and undefined in advance.

To connect an array of strings, you use join, like ["a", "b"].join("-") # → "a-b". Now in this case, you want to pair elements of the first array with elements of the second array.

array1.zip(array2).map(&:join)

This is short for:

array1.zip(array2) # → [['1-', 'FIRST'], ['2-', 'SECOND'], ['3-', 'THIRD']]
.map{ |pair|
  pair.join('') # ['1-', 'FIRST'].join('') → '1-FIRST'
} # → ['1-FIRST', '2-SECOND', '3-THIRD']

The method map is like each, but returns a new array with the return values of each iteration step. In comparison, each normally has no return value but can at most change the state of the system (e.g. you can insert results into a previously defined list).

You should also have been able to achieve join with each and + (if you don’t know how you could try it as an exercise) and lookup Array#join in ruby documentation.

2 Likes

Here is the solution:

   array1 = ['1-','2-','3-']
   array2 = ['FIRST','SECOND','THIRD']
   array1.zip(array2).map { |a| a.join('') }

I leave the topic open to that or I have another fundamental question. :grinning:

1 Like

Sorry Aerilius, I did not notice your answer because we posted at the same time.
Your solution is perfect and corresponds to what I had found.
Thanks for your intervention.

Whoopsie … it is actaully …

array1.zip(array2).map(&:join)
#=> ["1-FIRST", "2-SECOND", "3-THIRD"]

ie, the map argument is (&:join) not (:&join)


And can also use map! as the zip call has already created a new array object:

array1.zip(array2).map!(&:join)
#=> ["1-FIRST", "2-SECOND", "3-THIRD"]

The most “brute force” solution might be …

array3 = []
for i in 0..array1.size-1
  array3 << array1[i] + array2[i]
end

… or similar …

array3 = []
array1.each_with_index do |e,i|
  array3 << e + array2[i]
end

BUT, this “zipping” of arrays together is exactly what zip() was meant to make easier and faster.

And another beauty of #zip is that it will blend together as many Enumerables as you pass as arguments, even Enumerables of different derived Classes!

1 Like

Actually, I found an even more basic brute force method …

array3 = Array::new(array1.size) {|i| array1[i] + array2[i] }

… by just using the Array class constructor’s 3rd (block) form.

Still, not as elegant as …

array1.zip(array2).map!(&:join)

… but then the constructor need not create temporary nested arrays for each value pair.
For repetitive operations using very large arrays, the constructor method may be faster.

2 Likes

There’s always:

array3 = array1.map.with_index { |a1, i| "#{a1}#{array2[i]}" }
1 Like

Dan,

Good point. I use lots of hash constructors, but I tend to forget about the array form you used.

Please try and not use the :: notation, rubocop would not be happy, and I suspect for new coders it’s a ‘What?..’

Greg

1 Like
(OFF-TOPIC, re: MSP_Greg) "Please try and not use the :: notation ..."

This notation is from the style used when I learned Ruby (from a book I think Matz himself was involved with.)

And I prefer it, and will continue to use it.

It makes it obvious that the call is to a class or module method, whereas “dot notation” I use by convention to call an instance method.

(P.S. - I’ve 40y in engineering, 35y programming in 8+ coding languages, and 10y with Ruby. I’ve examined various recommended Ruby coding style guides. And use a hybrid of my own. I’m old enough, experienced enough, and well able to decide what kind of notation I will use.)

Not an issue (for me) as I do not use it.

It enforces bbatsov’s coding style guide, which I believe is stuffed full of arbitrarily chosen rules (many involving spacing and other trivial things) that are not accompanied with reasoning. Therefore they are bbatsov’s personal preferences and are meaningless to me.

Who died and made bbatsov “king of Ruby code” anway ?

I operate with a very terse (unwritten) style guide with rule number (1) being “make it readable and it’ll be maintainable”. Rule (2) is “no arbitrary nit-picky rules are needed.”

Not everyone attempts to write “pretty code”.
Some of the code in the Ruby Standard Library is formated quite ugly.

So? They need to learn some how, and sometime.
If it causes them to ask (which they’ve done here in the forums before,) or to go look up the scope operator in a book, so much the better. It is a learning opportunity.

1 Like

Another basic example:

array = []
array << s.definition.name unless s.definition.name.include?"PN" unless s.definition.name.include?"TOTO"

How to make it easier to exclude the definitions that have in their names the chains “PN” and “TOTO”?

Thank you

I won’t argue the :: vs . notation question because I agree that is a matter of individual style. But I agree 100% that the :: notation for name scope is a basic part of Ruby syntax, so any “What?” reaction indicates the reader has not bothered to learn the fundamentals yet!

1 Like

Recently in either Ruby or a commonly used gem repo someone fixed a comment that used the :: notation for a method/attribute call. Obviously, it’s still used for constants…

(OFF-TOPIC, re: MSP_Greg) "... someone fixed a comment ..."

(1) Why would you think I’d care what “someone” (who I obviously cannot know,) did in a comment of all things ?
I don’t, BTW.

(2) File: calling_methods.rdoc [Ruby 2.0.0] says clearly:

You may also use :: to designate a receiver, but this is rarely used due to the potential for confusion with :: for namespaces.

To which I retort, that there is no confusion as I follow Ruby convention that method names are lower case with underscore word separation, and namespaces are CamelCase.

If some reader is so untalented that they are so easily confused, then they should find something else to do than programming. And if they don’t “like” my code, then they may ignore it and me.

(3) You should have begun a new topic thread to discuss this, as you are hijacking this “Array” topic.

(4) Perhaps you forget how you treated ME in the following post:

  • Observers – why subclass? - #5 by MSP_Greg
    I do not forget. (I requested moderation on it then, but received no satisfaction from Admin.) So since then, as long as this remains posted, I will not and do not care for your opinions, Greg!
3 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.