String concatenation/distribution across 2 lists

Hi,

Newbie in Q here… Most probably quite obvious for you guys, but I have trouble concatenating 2 list of strings through distribution of the second (only) list’s nested levels. 


i.e. given:


a:(“a0”;“a1”;“a2”)
b:((“b00”;“b01”);(“b10”;“b11”;“b12”);“c20”)


what I wish for is a list (c) built by “distributing” (a) over its corresponding (b) index’s nested lists/atoms :


c:
(“a0”;“b00”)
(“a0”;“b01”)
(“a1”;“b10”)
(“a1”;“b11”)
(“a1”;“b12”)
(“a2”;“c20”)


Your help would be much appreciated… Thx!

raze a,/:'b

“a0b00”

“a0b01”

“a1b10”

“a1b11”

“a1b12”

“a2c20”

That what you need?

It’s easier if a and b have elements of uniform type so:

q)a:enlist each (“a0”;“a1”;“a2”)
q)b:((“b00”;“b01”);(“b10”;“b11”;“b12”);enlist “c20”)

q)raze raze a (;)/::’ b
“a0” “b00”
“a0” “b01”
“a1” “b10”
“a1” “b11”
“a1” “b12”
“a2” “c20”

HTH,
Pawel Tryfon

2014-03-25 17:54 GMT+01:00 Sean O’Hagan <sohagan857@gmail.com>:

raze a,/:'b

“a0b00”

“a0b01”

“a1b10”

“a1b11”

“a1b12”

“a2c20”

That what you need?

Thx Sean,

But unless I’m doing something wrong, your code yields:

(“a0b00”;“a0b01”;“a1b10”;“a1b11”;“a1b12”;“a2c”;“a22”;“a20”)

The last 3 elements of the resulting list (a[3] concatenated with individual b[3] characters) should not be included...

JP

Thx Pawel,

The proposed code does work, though I suspect the <enlisting> of singletons in the (b) list would cause me problems, as I do not know a priori which elements of list (b) are unique.

To clarify, my goal is to build a list of file paths, from an undetermined number of directories (list a), themselves containing an undetermined number of data files (list b).  Then use this resulting (c) list to input data in a single kdb file with 0:. 

If there is a more elegant way to proceed, feel free!  Thx

JP

>as I do not know a priori which elements of list

You would have to do a “type each b” ?to figure out where you have a character array and enlist the ones that yield 10h in that case.

q)b

(“b00”;“b01”)

(“b10”;“b11”;“b12”)

“c20”

q)@[b;where 10h=type each b;enlist]

(“b00”;“b01”)

(“b10”;“b11”;“b12”)

,“c20”

<o:p> </o:p>

>>> To clarify, my goal is to build a list of file paths, from an undetermined number of directories (list a), themselves containing an undetermined number of data files (list b).  Then use this resulting (c) list to input data in a single kdb file with 0:.  <o:p></o:p>

<o:p> </o:p>

If there is a more elegant way to proceed, feel free!  Thx<o:p></o:p>

<o:p> </o:p>

I would suggest to work with .Q.dd instead. See example codes:<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

/ current working directory<o:p></o:p>

cwd:`:.<o:p></o:p>

<o:p> </o:p>

/ get the contents<o:p></o:p>

(::)d: key dir<o:p></o:p>

<o:p> </o:p>

/ get the files<o:p></o:p>

r where f:r~'key@'r:.Q.dd[dir] @'d<o:p></o:p>

<o:p> </o:p>

/ get the directories<o:p></o:p>

r where not f<o:p></o:p>

<o:p> </o:p>

HTH,<o:p></o:p>

<o:p> </o:p>

Kim<o:p></o:p>

<o:p> </o:p>

Von: personal-kdbplus@googlegroups.com [mailto:personal-kdbplus@googlegroups.com] Im Auftrag von JP
Gesendet: Mittwoch, 26. März 2014 01:08
An: personal-kdbplus@googlegroups.com
Betreff: Re: [personal kdb+] Re: String concatenation/distribution across 2 lists<o:p></o:p>

<o:p> </o:p>

Thx Pawel,<o:p></o:p>

<o:p> </o:p>

The proposed code does work, though I suspect the <enlisting> of singletons in the (b) list would cause me problems, as I do not know a priori which elements of list (b) are unique.<o:p></o:p>

<o:p> </o:p>

To clarify, my goal is to build a list of file paths, from an undetermined number of directories (list a), themselves containing an undetermined number of data files (list b).  Then use this resulting (c) list to input data in a single kdb file with 0:.  <o:p></o:p>

<o:p> </o:p>

If there is a more elegant way to proceed, feel free!  Thx<o:p></o:p>

JP

To get proper result using Sean’s solution you need enlisting
So
If b:((“b00”;“b01”);(“b10”;“b11”;“b12”);enlist “c20”)

JP,

Try this one:

q)(hsym $a) {.Q.dd[x;] each y}' $b

HTH,
Pawel Tryfon

2014-03-26 9:50 GMT+01:00 Manish Patel <manni.patel@gmail.com>:

>as I do not know a priori which elements of list

You would have to do a “type each b”  to figure out where you have a character array and enlist the ones that yield 10h in that case.

q)b

(“b00”;“b01”)

(“b10”;“b11”;“b12”)

“c20”

q)@[b;where 10h=type each b;enlist]

(“b00”;“b01”)

(“b10”;“b11”;“b12”)

,“c20”

Great… I did indeed redefine it…

b2:b:((“b00”;“b01”);(“b10”;“b11”;“b12”);enlist “c20”)

Looks like .Q.dd is your way forward.

Thank you all,

  • Manish,your solution for generalized nested (or not) string lists works perfectly.

  • The ‘directory listing’ specific solutions proposed by Kuentang & Pawel are also very fine. Interestingly, I found a post by Attila in a similar context a few years ago that yields an elegant/compact function:

{$[-11=type f:key x; f; .z.s each` sv’x,/:f]}

I realize more and more that .z.s is definitely of great use in many instances… Again, thanks for your precious help.

JP

Just something extra here:

you can also use over (/) to control the level of depth you want to list the directory too:

f:{raze{$[x~k:key x;x;` sv’x,/:k]}@'x}/[;]

f[2;`:.]        / depth level 2

Or which ever that fancy you :)

Indeed, a useful twist… Thx

Nice!