split to walk into an HoH ?
hello people, removing shell scripts is a good way to learn raku and compare. today i want to replace this: fix () { awk -F, '{print $1" "$2}' | sort -u | awk -F" " '{ if (seen == $1) print "\t"$2; else { seen = $1; print $1 } }' } and i got this: fix () perl6 -e ' my %section; lines.map: { my ($s,$ss) = .split(","); %section{$s;$ss} = 1; } %section.keys.map: { .say for $_ , |%section{$_}.keys.map: {"\t$_"} } ' ";" to walk in the hoh is really awesome but i don't know even know from where i know it and what's the object underneath. it isn't listed in the list of operators (https://docs.perl6.org/language/operators). i would like to know because it would be nice to make this block my ($s,$ss) = .split(","); %section{$s;$ss} = 1; a one liner so i'm searching for something like %section{ .split(",").walkTheHash } = 1; any help will be warmly welcome. regards marc
Re: split to walk into an HoH ?
Could you post some input and expected output? That would make it easier for me (and perhaps others) to see what exactly you're trying to accomplish, in practical terms. On Fri, 22 Nov 2019 14:39:33 +0100 Marc Chantreux wrote: > hello people, > > removing shell scripts is a good way to learn raku and compare. > today i want to replace this: > > fix () { > awk -F, '{print $1" "$2}' | > sort -u | > awk -F" " '{ > if (seen == $1) print "\t"$2; > else { seen = $1; print $1 } > }' > } > > and i got this: > > fix () perl6 -e ' > my %section; > lines.map: { > my ($s,$ss) = .split(","); > %section{$s;$ss} = 1; > } > %section.keys.map: > { .say for $_ , |%section{$_}.keys.map: {"\t$_"} } > ' > > ";" to walk in the hoh is really awesome but i don't know even know > from where i know it and what's the object underneath. > it isn't listed in the list of operators > (https://docs.perl6.org/language/operators). > > i would like to know because it would be nice to make this block > > my ($s,$ss) = .split(","); > %section{$s;$ss} = 1; > > a one liner so i'm searching for something like > > %section{ .split(",").walkTheHash } = 1; > > any help will be warmly welcome. > > regards > marc -- With kind regards, Patrick Spek www: https://www.tyil.nl/ mail: p.s...@tyil.nl pgp: 1660 F6A2 DFA7 5347 322A 4DC0 7A6A C285 E2D9 8827 social: https://soc.fglt.nl/tyil git:https://gitlab.com/tyil/ pgpCNSMENxBRN.pgp Description: OpenPGP digital signature
Re: split to walk into an HoH ?
On 2019-11-22 Marc Chantreux wrote: > ";" to walk in the hoh is really awesome but i don't know even know > from where i know it and what's the object underneath. > it isn't listed in the list of operators It's mentioned in the page about subscripts: https://docs.perl6.org/language/subscripts#Multiple_dimensions (it's not easy to find, though, unless you know already that it's there) The method seems to be:: multi sub postcircumfix:<[; ]>(\SELF, @indices) and its adverbial variants. This works:: my %section = ( a => %( b => %( c => 1 ) ) ); my @path = «a b c»; say postcircumfix:<{; }>(%section,@path); and prints ``(1)`` (the return value is a list) From a quick look through ``Perl6/Grammar.nqp`` and ``Perl6/Actions.nqp``, I think that the semicolon is special-cased by the compiler, so the slightly ugly way above (call the operator directly) is probably the only way that works. -- Dakkar - GPG public key fingerprint = A071 E618 DD2C 5901 9574 6FE2 40EA 9883 7519 3F88 key id = 0x75193F88
Fwd: split to walk into an HoH ?
Hi Marc, I did a search for 'semicolon' on the following page and found the interesting text below. Semicolons are used to create multidimensional lists, maybe that's what's going on in your code? https://docs.perl6.org/language/list "Lists of Lists can also be created by combining comma and semicolon. This is also called multi-dimensional syntax, because it is most often used to index multidimensional arrays." "Unlike a comma, a hanging semicolon does not create a multidimensional list in a literal. However, be aware that this behavior changes in most argument lists, where the exact behavior depends on the function... ." "Because the semicolon doubles as a statement terminator it will end a literal list when used at the top level, instead creating a statement list. If you want to create a statement list inside parenthesis, use a sigil before the parenthesis... ." HTH, Bill. PS I would presume some variation of 'next' would work where you're using 'walkTheHash', but I don't really know for sure. On Fri, Nov 22, 2019 at 5:45 AM Marc Chantreux wrote: > > hello people, > > removing shell scripts is a good way to learn raku and compare. > today i want to replace this: > > fix () { > awk -F, '{print $1" "$2}' | > sort -u | > awk -F" " '{ > if (seen == $1) print "\t"$2; > else { seen = $1; print $1 } > }' > } > > and i got this: > > fix () perl6 -e ' > my %section; > lines.map: { > my ($s,$ss) = .split(","); > %section{$s;$ss} = 1; > } > %section.keys.map: > { .say for $_ , |%section{$_}.keys.map: {"\t$_"} } > ' > > ";" to walk in the hoh is really awesome but i don't know even know > from where i know it and what's the object underneath. > it isn't listed in the list of operators > (https://docs.perl6.org/language/operators). > > i would like to know because it would be nice to make this block > > my ($s,$ss) = .split(","); > %section{$s;$ss} = 1; > > a one liner so i'm searching for something like > > %section{ .split(",").walkTheHash } = 1; > > any help will be warmly welcome. > > regards > marc
Re: split to walk into an HoH ?
hello, On Fri, Nov 22, 2019 at 03:07:28PM +0100, Patrick Spek via perl6-users wrote: > Could you post some input and expected output? That would make it > easier for me (and perhaps others) to see what exactly you're trying to > accomplish, in practical terms. sorry ... i'm so confortable with awk i haven't though about some are not. i sincerely apologize. Basically i want to figure out what are the sections, subsections of of a CSV file: A,1,garbage . A,2,garbage . A,2,garbage . A,2,garbage . A,3,garbage . A,3,garbage . A,3,garbage . B,1,garbage . B,2,garbage . B,2,garbage . B,2,garbage . B,3,garbage . B,3,garbage . B,3,garbage . becomes A 1 2 3 B 1 2 3 regards, marc
Re: split to walk into an HoH ?
> From a quick look through ``Perl6/Grammar.nqp`` and > ``Perl6/Actions.nqp``, I think that the semicolon is special-cased by > the compiler, so the slightly ugly way above (call the operator > directly) is probably the only way that works. *this* is the level of expertise i miss :) thanks for your reply. marc
Re: split to walk into an HoH ?
> On Nov 22, 2019, at 9:06 AM, Marc Chantreux wrote: > > hello, > > On Fri, Nov 22, 2019 at 03:07:28PM +0100, Patrick Spek via perl6-users wrote: >> Could you post some input and expected output? That would make it >> easier for me (and perhaps others) to see what exactly you're trying to >> accomplish, in practical terms. > > sorry ... i'm so confortable with awk i haven't though about some are > not. i sincerely apologize. > > Basically i want to figure out what are the sections, subsections of of > a CSV file: > >A,1,garbage . >A,2,garbage . >A,2,garbage . >A,2,garbage . >A,3,garbage . >A,3,garbage . >A,3,garbage . >B,1,garbage . >B,2,garbage . >B,2,garbage . >B,2,garbage . >B,3,garbage . >B,3,garbage . >B,3,garbage . > > becomes > >A >1 >2 >3 >B >1 >2 >3 > > regards, > marc Marc, When I run your original Awk code against the .csv data you listed above, I get this output: A 2 3 B 2 3 The first key of each second level is missing, which differs from your sample output above. Have I corrupted your Awk code, or have I misunderstood something, or what? -- Thank you, Bruce Gray (Util of PerlMonks)
Re: split to walk into an HoH ?
Hi Marc, here's a one-liner based on the classify method, which you may find to be an interesting jumping-off-point, or centerpiece: perl6 -e 'use JSON::Fast; my %foo = lines()>>.trim-leading.classify(*.split(",").head(2)); say to-json %foo' A,1,garbage . A,2,garbage . A,2,garbage . A,2,garbage . A,3,garbage . A,3,garbage . A,3,garbage . B,1,garbage . B,2,garbage . B,2,garbage . B,2,garbage . B,3,garbage . B,3,garbage . B,3,garbage . { "A": { "3": [ "A,3,garbage .", "A,3,garbage .", "A,3,garbage ." ], "1": [ "A,1,garbage ." ], "2": [ "A,2,garbage .", "A,2,garbage .", "A,2,garbage ." ] }, "B": { "3": [ "B,3,garbage .", "B,3,garbage .", "B,3,garbage ." ], "1": [ "B,1,garbage ." ], "2": [ "B,2,garbage .", "B,2,garbage .", "B,2,garbage ." ] } } Things to note are: it makes hashes, so the order isn't retained. if that's important, you could, for example, use/build a Hash that retains its key insertion order and call .categorize-list on an instance of it. Hope that helps, and Good Luck! - Timo On 22/11/2019 16:06, Marc Chantreux wrote: > hello, > > On Fri, Nov 22, 2019 at 03:07:28PM +0100, Patrick Spek via perl6-users wrote: >> Could you post some input and expected output? That would make it >> easier for me (and perhaps others) to see what exactly you're trying to >> accomplish, in practical terms. > sorry ... i'm so confortable with awk i haven't though about some are > not. i sincerely apologize. > > Basically i want to figure out what are the sections, subsections of of > a CSV file: > > A,1,garbage . > A,2,garbage . > A,2,garbage . > A,2,garbage . > A,3,garbage . > A,3,garbage . > A,3,garbage . > B,1,garbage . > B,2,garbage . > B,2,garbage . > B,2,garbage . > B,3,garbage . > B,3,garbage . > B,3,garbage . > > becomes > > A > 1 > 2 > 3 > B > 1 > 2 > 3 > > regards, > marc
Re: split to walk into an HoH ?
> On Nov 22, 2019, at 9:57 AM, Marc Chantreux wrote: > > On Fri, Nov 22, 2019 at 06:20:51AM -0800, William Michels via perl6-users > wrote: >> Hi Marc, I did a search for 'semicolon' on the following page and >> found the interesting text below. Semicolons are used to create >> multidimensional lists, maybe that's what's going on in your code? > > indeed! i tried with ";" but it wasn't that helpful. :) > >> PS I would presume some variation of 'next' would work where you're >> using 'walkTheHash', but I don't really know for sure. > > Gianni gave the solution: my script became: > >fix () perl6 -e ' >my %section; >lines.map: {postcircumfix:<{; }>( %section, .split(",") ) = 1 }; >%section.keys.map: { .say for $_ , |%section{$_}.keys.map: {"\t$_"} } >' > > it would be nice to have a shorter syntax to access to access to > postcircumfix:<{; }> but still: it's awesome. > > regards > > marc FWIW, I would make %section an HoA, which would be a less compact structure in memory, but allows more succinct manipulation, like so: my %section = lines() .map( *.split(",") ) .classify( { .[0] }, :as{ .[1] } ); for %section.sort { say .key; say "\t$_" for .value.sort.unique; }
Re: split to walk into an HoH ?
hello Bruce, > The first key of each second level is missing, which differs from your sample > output above. > Have I corrupted your Awk code, or have I misunderstood something, or what? you just spotted a bug: the first subkey *is* indeed required. actually fixing the bug makes the awk version even shorter. fix () { awk -F, '{print $1" "$2}' | sort -u | awk -F" " ' seen != $1 { seen = $1; print $1 } { print "\t"$2 } ' } regards marc
Re: split to walk into an HoH ?
inline: On Fri, Nov 22, 2019 at 7:20 AM Bruce Gray wrote: > > > > > On Nov 22, 2019, at 9:06 AM, Marc Chantreux wrote: > > > > hello, > > > > On Fri, Nov 22, 2019 at 03:07:28PM +0100, Patrick Spek via perl6-users > > wrote: > >> Could you post some input and expected output? That would make it > >> easier for me (and perhaps others) to see what exactly you're trying to > >> accomplish, in practical terms. > > > > sorry ... i'm so confortable with awk i haven't though about some are > > not. i sincerely apologize. > > > > Basically i want to figure out what are the sections, subsections of of > > a CSV file: > > > >A,1,garbage . > >A,2,garbage . > >A,2,garbage . > >A,2,garbage . > >A,3,garbage . > >A,3,garbage . > >A,3,garbage . > >B,1,garbage . > >B,2,garbage . > >B,2,garbage . > >B,2,garbage . > >B,3,garbage . > >B,3,garbage . > >B,3,garbage . > > > > becomes > > > >A > >1 > >2 > >3 > >B > >1 > >2 > >3 > > > > regards, > > marc > > Marc, > > When I run your original Awk code against the .csv data you listed above, I > get this output: > A > 2 > 3 > B > 2 > 3 > The first key of each second level is missing, which differs from your sample > output above. > Have I corrupted your Awk code, or have I misunderstood something, or what? > > -- > Thank you, > Bruce Gray (Util of PerlMonks) I get the same result using awk as Bruce, although I unpacked Marc's awk code into a (long) one-liner: mbook:~ homedir$ cat awk_test1.csv | awk -F, '{print $1" "$2}' | sort -u | awk -F" " '{if (seen == $1) print "\t"$2; else { seen = $1; print $1 }}' A 2 3 B 2 3 mbook:~ homedir$ HTH, Bill.
Re: split to walk into an HoH ?
hello Timo, > lines()>>.trim-leading.classify(*.split(",").head(2)); say to-json %foo' which led me to this solution: fix () perl6 -e ' lines.classify(*.split(",").head(2)).pairs.map: { .say for .key, |.value.map({ "\t" ~ .key }); } ' fix () perl6 -e ' lines\ .classify( *.split(",").head(2) ) .pairs .map: { .say for .key, |.value.map({ "\t" ~ .key }); } ' which is nice to read but hold much more data in memory. anyway: good point. regards marc
Re: split to walk into an HoH ?
> which led me to this solution: > fix () perl6 -e ' > lines.classify(*.split(",").head(2)).pairs.map: { > .say for .key, |.value.map({ "\t" ~ .key }); > } > ' Hi Marc, I tried the first solution you posted and the "subheaders" are returned out of order (e.g. "2,1,3" and not "1,2,3"): mbook:~ homedir$ cat p6_chunk_csv.p6 lines.classify(*.split(",").head(2)).pairs.map: { .say for .key, |.value.map({ "\t" ~ .key }); } mbook:~ homedir$ cat awk_test1.csv | perl6 p6_chunk_csv.p6 B 3 1 2 A 2 3 1 mbook:~ homedir$ HTH, Bill. On Fri, Nov 22, 2019 at 9:13 AM Marc Chantreux wrote: > > hello Timo, > > > lines()>>.trim-leading.classify(*.split(",").head(2)); say to-json %foo' > > which led me to this solution: > > fix () perl6 -e ' > lines.classify(*.split(",").head(2)).pairs.map: { > .say for .key, |.value.map({ "\t" ~ .key }); > } > ' > > fix () perl6 -e ' > lines\ > .classify( *.split(",").head(2) ) > .pairs > .map: { .say for .key, |.value.map({ "\t" ~ .key }); } > ' > > which is nice to read but hold much more data in memory. > anyway: good point. > > regards > marc
Re: split to walk into an HoH ?
hello, > FWIW, I would make %section an HoA, which would be a less compact > structure in memory, but allows more succinct manipulation, like so: > my %section = lines() > .map( *.split(",") ) > .classify( { .[0] }, :as{ .[1] } ); > for %section.sort { > say .key; > say "\t$_" for .value.sort.unique; > } then * no need of %section * no need to sort so it becames: fix () perl6 -e ' lines.map( *.split(",") ) .classify( { .[0] }, :as{ .[1] } ) .map: { say .key; say "\t$_" for .value.unique } ' even if the semicolon thing goes on scratching me, i'm really happy about this one! thanks a lot. regards marc
Re: split to walk into an HoH ?
hello, > Hi Marc, I tried the first solution you posted and the "subheaders" > are returned out of order (e.g. "2,1,3" and not "1,2,3"): you're right but it doesn't matter in this usecase. > mbook:~ homedir$ cat p6_chunk_csv.p6 > lines.classify(*.split(",").head(2)).pairs.map: { > .say for .key, |.value.map({ "\t" ~ .key }); > } > mbook:~ homedir$ cat awk_test1.csv | perl6 p6_chunk_csv.p6 useless use of cat: as lines() works on $*ARGFILES, you can just write: perl6 p6_chunk_csv.p6 awk_test1.csv thanks for helping me regards marc
Re: split to walk into an HoH ?
On Friday, November 22, Marc Chantreux wrote: > so it becames: > > fix () perl6 -e ' > lines.map( *.split(",") ) > .classify( { .[0] }, :as{ .[1] } ) > .map: { say .key; say "\t$_" for .value.unique } > ' You could also use the feed operator perl6 -e ' lines() ==> map({split(",", $_)}) ==> classify( {.[0]}, :as{.[1]}) ==> sort() # optional ==> map({ say .key; say "\t$_" for .value.unique })' in.csv Brian
Re: split to walk into an HoH ?
hello, > You could also use the feed operator is there a reason to do so? i see none. regards marc
Re: split to walk into an HoH ?
On Friday, November 22, Marc Chantreux wrote: > hello, > > > You could also use the feed operator > > is there a reason to do so? i see none. I don't think so; just a stylistic choice -- though the documentation lists some potential benefits at the end of the section here https://docs.raku.org/language/operators#infix_==%3E (not being restricted to method chaining, and potential parallel operation in the future) Brian
Re: Fwd: split to walk into an HoH ?
On Fri, Nov 22, 2019 at 06:20:51AM -0800, William Michels via perl6-users wrote: > Hi Marc, I did a search for 'semicolon' on the following page and > found the interesting text below. Semicolons are used to create > multidimensional lists, maybe that's what's going on in your code? indeed! i tried with ";" but it wasn't that helpful. :) > PS I would presume some variation of 'next' would work where you're > using 'walkTheHash', but I don't really know for sure. Gianni gave the solution: my script became: fix () perl6 -e ' my %section; lines.map: {postcircumfix:<{; }>( %section, .split(",") ) = 1 }; %section.keys.map: { .say for $_ , |%section{$_}.keys.map: {"\t$_"} } ' it would be nice to have a shorter syntax to access to access to postcircumfix:<{; }> but still: it's awesome. regards marc
(syntaxic choices) Re: split to walk into an HoH ?
> I don't think so; just a stylistic choice well ... i tested ===> once because i'll choose any syntax that can spare me parenthesis especially in raku because i feel they are in the wrong place (scheme makes parenthesis right). Raku behaves better than perl in this regard because say (f 12), "works"; when Perl expect a +(f 12). But i doesn't spare anything so are ok for me :) regards marc