DISQUS

Phil Dawes' Stuff: More factor: tabular to triples

  • Neil Bartlett · 2 years ago
    Just for a laugh, here it is in Haskell. You can type this at the interpreter.

    let insertList x = map (insert x) where insert x (y,z) = (x,y,z)

    let cols = ["col1","col2","col3"]

    let rows = [["a","b","c"],["e","f","g"]]

    concat $ zipWith insertList [0..] $ map (zip cols) rows

    This prints [(0,"col1","a"),(0,"col2","b"),(0,"col3","c"),(1,"col1","e"),(1,"col2","f"),(1,"col3","g")]

    No preview available so I don't know if your blog software is going to mangle that!
  • paddy3118 · 2 years ago
    I thought from the input format and the output that a Python list comprehension would be the way I'd solve it and came up with this:

    >>> from pprint import pprint as pp
    >>> tabular = [["col1","col2","col3"],[["a","b","c"],["e","f","g"]]]
    >>> triples = [(row[0], col[1], row[1][col[0]])
    for row in enumerate(tabular[1])
    for col in enumerate(tabular[0])]
    >>> pp(triples)
    [(0, 'col1', 'a'),
    (0, 'col2', 'b'),
    (0, 'col3', 'c'),
    (1, 'col1', 'e'),
    (1, 'col2', 'f'),
    (1, 'col3', 'g')]
    >>>


    (I added a couple of newlines to the list comprehension to get it into the comment box).

    If I were using it then I might wrap it in a function and add a docstring to test/explain it.

    - Paddy.
  • Christopher Diggins · 2 years ago
    Hi Phil,

    Small typo in the first sentence: "I’ve been playing with for a couple of weeks.", I believe you meant "factor" instead of "for".

    If you are interested in concatenative languages and the semantic web have you seen Ripple? http://ripple.fortytwo.net/

    There is also my own relatively immature language Cat (http://www.cat-language.com), which will be stable "real soon now".

    Cheers,
    Christopher Diggins
  • Phil Dawes · 2 years ago
    Thanks Christopher - it was a missing close brace in the factor link preventing it from being displayed.
    I'll definitely check out both Cat and ripple - thanks for the links
  • Slava Pestov · 2 years ago
    Hi,

    I had a go at implementing this. The key, as you've noticed, is to decompose the problem into steps where you're working with no more than a handful of values at once.

    Don'write a big loop, instead break it up into multiple iterations over the data and use library words where possible.

    USE: math.ranges

    : (column-names) ( cols row -- pairs )
    2array flip ;

    : column-names ( cols rows -- seqs-of-pairs )
    [ (column-names) ] curry* map ;

    : (number-rows) ( pairs n -- triples )
    [ add* ] curry map ;

    : number-rows ( seqs-of-pairs -- triples )
    tuck length [a,b] [ (number-rows) ] 2map concat ;

    : tabular>triples ( start-rowid cols rows -- triples )
    column-names number-rows ;
  • Greg M · 2 years ago
    I prefer the Haskell list comprehension version:

    [(i,col,cell)|(i,row)<-zip [startid..] rows, (col,cell) <- zip cols row]

    Now I wonder how this will get formatted? Need a preview button.