11
\$\begingroup\$

Task

Read the contents of a table given a set of coordinates.

Table formatting

Tables will be in this basic format:

      |[name]|[name]|
---------------------
[name]| [val]|[val] |
[name]| [val]|[val] |

Column names are always unique within columns. Row names are also unique within rows. This includes names that are the same except whitespace. Values, col names and row names will never have |- inside them. Names and values will never have spaces inside them, but may have leading or trailing space. Col width is adjustable based on the header/content. Column width is always consistent from top to bottom.

Input

A table and a space separated list of [name]s.

Example

[table]
row col

If you are writing a function, these can be separate strings, otherwise the row col will always be the very last line in the input. row col has some flexibility for the format and may be represented many ways. (e.g. (row, col), r, c, ...). The only hard requirement is that it be one line, and that it must appear in the order col row.

Output

The contents of a cell specified by the input with no leading or trailing space from the cell.

Examples

In:
   |a|z |_*|
------------
atb|1|85|22|
b  |5|6 |e$|
/+*|8|we|th|
atb a

Out:
1


In:
  | x| b |
----------
ab|l |mmm|
b |le| l |
b b

Out:
l

In:
   |a|z |_*|  ab  |
-------------------
atb|1|85|22| 5    |
b  |5|6 |e$|  8   |
/+-|8|we|th| 126  |
atb ab

Out:
5
\$\endgroup\$
8
  • \$\begingroup\$ Will the cell requested in the input always exist in the table? \$\endgroup\$ Commented Jan 16, 2016 at 0:57
  • \$\begingroup\$ Oh, now I get it ;) Yes it will \$\endgroup\$
    – J Atkin
    Commented Jan 16, 2016 at 0:58
  • \$\begingroup\$ It seems that the input will be given as a single string though you have not made it explicit. How much flexibility is there on input format? Is passing an array of values to a function acceptable? (I'm guessing no, it has to be a string) Can the row/col be given as separate arguments to the table? (I'm guessing probably.) Please clarify. \$\endgroup\$ Commented Jan 16, 2016 at 1:02
  • \$\begingroup\$ Does that help? \$\endgroup\$
    – J Atkin
    Commented Jan 16, 2016 at 1:09
  • \$\begingroup\$ Don't columns go up/down and rows go left/right? I believe the coordinates in your examples are reversed. \$\endgroup\$ Commented Jan 16, 2016 at 2:04

3 Answers 3

5
\$\begingroup\$

JavaScript (ES6), 108

t=>(S=s=>s.split(/ *\| */),t=t.split`
`,[y,x]=t.pop().split` `,S(t.find(r=>S(r)[0]==y))[S(t[0]).indexOf(x)])

TEST in Firefox

f=t=>(
 S=s=>s.split(/ *\| */),
 t=t.split`\n`,
 [y,x]=t.pop().split` `,
 S(t.find(r=>S(r)[0]==y))[S(t[0]).indexOf(x)]
)

function test(){
  r=f(T.value);
  O.textContent=r
}
test()
#T { width: 50%; height: 9em}
Input<br><textarea id=T>   |a|z |_*|  ab  |
-------------------
atb|1|85|22| 5    |
b  |5|6 |e$|  8   |
/+-|8|we|th| 126  |
atb ab</textarea><br>
<button onclick="test()">Find</button>
<span id=O></span>

\$\endgroup\$
4
  • \$\begingroup\$ Nice, BTW Why just in firefox? (FWIW I use firefox) \$\endgroup\$
    – J Atkin
    Commented Jan 17, 2016 at 0:48
  • \$\begingroup\$ Last time I checked, Chrome had not yet implemented Destructuring assignment - Confirmed, this gives error in Chrome "Invalid left-hand side in assignment" \$\endgroup\$
    – edc65
    Commented Jan 17, 2016 at 0:51
  • \$\begingroup\$ @JAtkin BTW why not an upvote? \$\endgroup\$
    – edc65
    Commented Jan 17, 2016 at 0:55
  • \$\begingroup\$ I read from top to bottom, left a comment, had to do something else, and forgot ;) \$\endgroup\$
    – J Atkin
    Commented Jan 17, 2016 at 1:08
4
\$\begingroup\$

Haskell, 117 116 111 bytes

import Data.Lists
s=splitOn"|".filter(>' ')
(t#b)a|l<-lines t=[c|r<-l,(d,c)<-zip(s$l!!0)$s r,d==a,s r!!0==b]!!0

Usage example:

*Main> ("  | x| b |\n----------\nab|l |mmm|\nb |le| l |\nb b" # "b") "b"
"l"

How it works:

s=splitOn"|".filter(>' ')         -- helper function to remove spaces and split a
                                  -- line at bars into words
l<-lines t                        -- split table at \n into lines and bind to l
[c|r<-l,                      ]   -- take c for every line r in l, where
       (d,c)<-zip(s$l!!0)$s r     -- a pair (d,c) is made by zipping the (split)
                                  -- header of the table with the (split) line r 
        ,d==a                     -- and d (=header element) equals parameter a
        ,s r!!0==b                -- and the first word in r equals parameter b
                             !!0  -- pick the first (and only) element
\$\endgroup\$
2
\$\begingroup\$

Retina, 90 bytes

s`^(?=.*\n(.*) (.*))((?<a>\|)|.)*\|\s*\2\s*\|.*\n\1\s*((?<-a>\|)|[^|])*\|\s*([^\s|]*).*
$5

My first balancing group regex. It should be still well golfable. Will try to do it later.

The main idea is counting the pipes until the column name and then using the same amount of pipes up in the row starting with the desired row's name. After that we capture the next value which is the result.

Try it online here.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.