2

I have got the following Ruby hash:

hash = {
0 => "
===
@@@
@ @
@ @
@ @
@@@
===",
1 => "
=
@
@
@
@
@
="}

I would like to print out some of the values of the hash in one line in the console. To that effect, I have created an array with the elements I would like printed out:

test = [hash[0], hash[1]]

or

test1 = [hash[0], hash[0]]

In case I want to print test1 to the console, the result should be the following:

======
@@@@@@
@ @@ @
@ @@ @
@ @@ @
@@@@@@
======

In case I want to print `test2 to the console, the result should be:

====
@@@@
@ @@
@ @@
@ @@
@@@@
====

However, when I use puts or print, the result is always that one is printed after another and not in the same line.

franciscofcosta
  • 833
  • 5
  • 25
  • 53

2 Answers2

5
a1, a2 = hash.values.map { |s| s[1..-1].split("\n") }
  #=> [["===", "@@@", "@ @", "@ @", "@ @", "@@@", "==="],
  #    ["=", "@", "@", "@", "@", "@", "="]] 

puts a1.zip(a1).map(&:join)
======
@@@@@@
@ @@ @
@ @@ @
@ @@ @
@@@@@@
======

puts a1.zip(a2).map(&:join)
====
@@@@
@ @@
@ @@
@ @@
@@@@
====

Note:

a1.zip(a1)
  #=> [["===", "==="], ["@@@", "@@@"], ["@ @", "@ @"], ["@ @", "@ @"],
  #    ["@ @", "@ @"], ["@@@", "@@@"], ["===", "==="]]

a1.zip(a2)
  #=> [["===", "="], ["@@@", "@"], ["@ @", "@"], ["@ @", "@"],
  #    ["@ @", "@"], ["@@@", "@"], ["===", "="]] 

s[1..-1], which drops the first character of hash[0] and hash[1], is needed because that character is a newline ("\n"). Had the two lines 0 => " and === been written 0 =>"=== (similar for hash[1]), I could have written s.split("\n").

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • Thank you very much for your answer. I have implemented what you suggested and, in fact, they are now printing in the same line. However, they are printing with some space between each other. You can see ir here: https://drive.google.com/file/d/1udhbQQMqJWs-S7Ze7-byZxdMKRwMJllc/view?usp=sharing – franciscofcosta Jul 31 '19 at 04:58
  • I don't know why are you getting that result. I used your data (`hash`) and my code to produce the desired result, which I show. First confirm that you are using the hash `hash` given in your question. If you haven't done so, cut-and-paste the expression `hash = { ... }`, then run the code. – Cary Swoveland Jul 31 '19 at 05:18
  • Yes, I am using the exact same hash. – franciscofcosta Jul 31 '19 at 05:27
  • When you execute `a1, a2 = hash.values.map { |s| s[1..-1].split("\n") }` do you get the same return value as that shown in my answer? If you do, do you get the same return value as I show for `a1.zip(a1)`? – Cary Swoveland Jul 31 '19 at 06:15
3

You need to create a two-dimensional structure first to be able to get the wanted result.

I suggest the following steps:

  1. Deconstruct the values in your hash

    atomic = hash.values.map{ |e| e.split("\n")}
    

    This will give you

    [["",
      "===",
      "@@@",
      "@ @",
      "@ @",
      "@ @",
      "@@@",
      "==="
     ], [
      "",
      "=",
      "@",
      "@",
      "@",
      "@",
      "@",
      "="
     ]]
    
  2. Use the new data structure to build the output you need

    first case:

    test1 = atomic[0].zip(atomic[0]).map(&:join)
    puts test1
    

    =>

    ======
    @@@@@@
    @ @@ @
    @ @@ @
    @ @@ @
    @@@@@@
    ======
    

    second case:

    test2 = atomic[0].zip(atomic[1]).map(&:join)
    

    =>

    ====
    @@@@
    @ @@
    @ @@
    @ @@
    @@@@
    ====
    

I hope you find that helpful.

wteuber
  • 1,208
  • 9
  • 15
  • Your answer seems to be the same as my earlier answer. Am I missing something? – Cary Swoveland Jul 30 '19 at 23:32
  • Thank you very much for your answer. I have implemented what you suggested and, in fact, they are now printing in the same line. However, they are printing with some space between each other. You can see ir here: https://drive.google.com/file/d/1udhbQQMqJWs-S7Ze7-byZxdMKRwMJllc/view?usp=sharing – franciscofcosta Jul 31 '19 at 04:58
  • Hi @franciscofcosta, I realized that I found the same solution after I posted it. I think Cary and i have been typing our answers at the same time, he was simply faster :-). I can't see where the spaces come from. For me `test1` looks like this: `["", "======", "@@@@@@", "@ @@ @", "@ @@ @", "@ @@ @", "@@@@@@", "======"]` (no spaces here), could you post your `test1.inspect` so we work backwards to find the issue? – wteuber Jul 31 '19 at 06:47
  • Hi @knugie, thanks for the reply. I just did `test1.inspect` and I get this: `["", " === ===", " @@@ @@@", " @ @ @ @", " @ @ @ @", " @ @ @ @", " @@@ @@@", " === ==="]`. As you can see, it's not exactly the same as you have. I've got spaces in the second and last elements of the array. – franciscofcosta Jul 31 '19 at 08:19
  • 1
    I see what the issue is now. in your original post, the trailing spaces have been removed automatically. That's why Cary and I didn't see them. I see two sensible options of fixing that. First, remove the trailing white spaces in your original `hash` before processing it. And second, `strip` trailing whitespace of each line like so: `atomic = hash.values.map{ |e| e.split("\n").map(&:strip)}`. Does that help? – wteuber Jul 31 '19 at 20:14
  • Because there are only trailing whitespaces but no leading ones, you could use `chomp` instead of `strip` - your choice. – wteuber Jul 31 '19 at 20:39
  • Thank you! I was on my way to write the exact same thing. Thanks so much for your help! If I had more than 2 elements in the hash, would I be able to combine them the same way? Let's say if I had a `test3` that I would like to show up after `test2`? – franciscofcosta Aug 01 '19 at 08:34
  • Yes, absolutely. – wteuber Aug 02 '19 at 19:12