Discussion:
[Bug-apl] Help with APL expression
Elias Mårtenson
2017-07-05 09:43:34 UTC
Permalink
I have a list of strings, and a corresponding set of categorisations:


* strings ← 'foo' 'bar' 'abc' 'def' 'ghi' 'jkl'*
* categories ← 1 1 0 2 1 0*

I now need to group these strings according to category. In other words,
when applying operation X, I need the following output:

* categories X strings*
┏→━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃┏→━━━━━━━━━━┓ ┏→━━━━━━━━━━━━━━━━┓ ┏→━━━━┓┃
┃┃"abc" "jkl"┃ ┃"foo" "bar" "hgi"┃ ┃"def"┃┃
┃┗∊━━━━━━━━━━┛ ┗∊━━━━━━━━━━━━━━━━┛ ┗∊━━━━┛┃
┗∊∊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

What is the best way to solve this?
Louis de Forcrand
2017-07-05 10:48:44 UTC
Permalink
Is it important that they be grouped in the order specified by the key?
If not, this should do (with C the categories and S the strings):

(⊂[1]C∘.=∪C)/¹⊂S

If they must be ordered, then this can do it:

(⊂[1]C∘.=U[⍋U←∪C])/¹⊂S

In addition, the categories don’t have to be numbers.

Note that Dyalog’s (dyadic) key function is equivalent to this, with L being
the operator’s left operand:

Lš(⊂[1]C∘.=∪C)/¹⊂S

Cheers,
Louis
Post by Elias MÃ¥rtenson
strings ← 'foo' 'bar' 'abc' 'def' 'ghi' 'jkl'
categories ← 1 1 0 2 1 0
categories X strings
┏→━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃┏→━━━━━━━━━━┓ ┏→━━━━━━━━━━━━━━━━┓ ┏→━━━━┓┃
┃┃"abc" "jkl"┃ ┃"foo" "bar" "hgi"┃ ┃"def"┃┃
┃┗∊━━━━━━━━━━┛ ┗∊━━━━━━━━━━━━━━━━┛ ┗∊━━━━┛┃
┗∊∊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
What is the best way to solve this?
Ala'a Mohammad
2017-07-06 21:38:57 UTC
Permalink
Hi,
Another two ways, Not as compact or optimized, but generate the same output
1)
G groups, C categories, and S strings

G←(⍴∪C)⍴⊂⍬ ◊ C {G[⍺]←⊂(⊃G[⍺]),⊂⍵}¨S ◊ G

I forgot how to suppress the middle output
or in a function

∇ groups ← categories group items
groups ← (⍴∪categories)⍴⊂⍬
categories {groups[⍺]←⊂(⊃groups[⍺]),⊂⍵}¨ items

2)
(1+C[x]) ⊂ S[(⍳⍴C)[x←⍋C]]

Best wishes,

Ala'a
Post by Louis de Forcrand
Is it important that they be grouped in the order specified by the key?
(⊂[1]C∘.=∪C)/¨⊂S
(⊂[1]C∘.=U[⍋U←∪C])/¨⊂S
In addition, the categories don’t have to be numbers.
Note that Dyalog’s (dyadic) key function is equivalent to this, with L being
L¨(⊂[1]C∘.=∪C)/¨⊂S
Cheers,
Louis
strings ← 'foo' 'bar' 'abc' 'def' 'ghi' 'jkl'
categories ← 1 1 0 2 1 0
I now need to group these strings according to category. In other words,
categories X strings
┏→━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃┏→━━━━━━━━━━┓ ┏→━━━━━━━━━━━━━━━━┓ ┏→━━━━┓┃
┃┃"abc" "jkl"┃ ┃"foo" "bar" "hgi"┃ ┃"def"┃┃
┃┗∊━━━━━━━━━━┛ ┗∊━━━━━━━━━━━━━━━━┛ ┗∊━━━━┛┃
┗∊∊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
What is the best way to solve t
Ala'a Mohammad
2017-07-06 21:54:01 UTC
Permalink
Oops, the second solution should be

(1+c[x]) ⊂ s[x←⍋c]

Ala'a
Post by Ala'a Mohammad
Hi,
Another two ways, Not as compact or optimized, but generate the same output
1)
G groups, C categories, and S strings
G←(⍴∪C)⍴⊂⍬ ◊ C {G[⍺]←⊂(⊃G[⍺]),⊂⍵}¨S ◊ G
I forgot how to suppress the middle output
or in a function
∇ groups ← categories group items
groups ← (⍴∪categories)⍴⊂⍬
categories {groups[⍺]←⊂(⊃groups[⍺]),⊂⍵}¨ items
2)
(1+C[x]) ⊂ S[(⍳⍴C)[x←⍋C]]
Best wishes,
Ala'a
Post by Louis de Forcrand
Is it important that they be grouped in the order specified by the key?
(⊂[1]C∘.=∪C)/¨⊂S
(⊂[1]C∘.=U[⍋U←∪C])/¨⊂S
In addition, the categories don’t have to be numbers.
Note that Dyalog’s (dyadic) key function is equivalent to this, with L being
L¨(⊂[1]C∘.=∪C)/¨⊂S
Cheers,
Louis
strings ← 'foo' 'bar' 'abc' 'def' 'ghi' 'jkl'
categories ← 1 1 0 2 1 0
I now need to group these strings according to category. In other words,
categories X strings
┏→━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃┏→━━━━━━━━━━┓ ┏→━━━━━━━━━━━━━━━━┓ ┏→━━━━┓┃
┃┃"abc" "jkl"┃ ┃"foo" "bar" "hgi"┃ ┃"def"┃┃
┃┗∊━━━━━━━━━━┛ ┗∊━━━━━━━━━━━━━━━━┛ ┗∊━━━━┛┃
┗∊∊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
What is the best way to solve thi
Christian Robert
2017-07-07 05:43:20 UTC
Permalink
That kind of expression really get me on my knees.

thanks for sharing,

Xtian.
Post by Ala'a Mohammad
Oops, the second solution should be
(1+c[x]) ⊂ s[x←⍋c]
Ala'a
Post by Ala'a Mohammad
Hi,
Another two ways, Not as compact or optimized, but generate the same output
1)
G groups, C categories, and S strings
G←(⍴∪C)⍴⊂⍬ ◊ C {G[⍺]←⊂(⊃G[⍺]),⊂⍵}¨S ◊ G
I forgot how to suppress the middle output
or in a function
∇ groups ← categories group items
groups ← (⍴∪categories)⍴⊂⍬
categories {groups[⍺]←⊂(⊃groups[⍺]),⊂⍵}¨ items
2)
(1+C[x]) ⊂ S[(⍳⍴C)[x←⍋C]]
Best wishes,
Ala'a
Post by Louis de Forcrand
Is it important that they be grouped in the order specified by the key?
(⊂[1]C∘.=∪C)/¨⊂S
(⊂[1]C∘.=U[⍋U←∪C])/¨⊂S
In addition, the categories don’t have to be numbers.
Note that Dyalog’s (dyadic) key function is equivalent to this, with L being
L¨(⊂[1]C∘.=∪C)/¨⊂S
Cheers,
Louis
strings ← 'foo' 'bar' 'abc' 'def' 'ghi' 'jkl'
categories ← 1 1 0 2 1 0
I now need to group these strings according to category. In other words,
categories X strings
┏→━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃┏→━━━━━━━━━━┓ ┏→━━━━━━━━━━━━━━━━┓ ┏→━━━━┓┃
┃┃"abc" "jkl"┃ ┃"foo" "bar" "hgi"┃ ┃"def"┃┃
┃┗∊━━━━━━━━━━┛ ┗∊━━━━━━━━━━━━━━━━┛ ┗∊━━━━┛┃
┗∊∊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
What is the best way t
Louis de Forcrand
2017-07-07 00:20:16 UTC
Permalink
I rather like your second solution. It's faster than mine, and sorts the items for free too!

Well done!
Louis
Post by Ala'a Mohammad
Oops, the second solution should be
(1+c[x]) ⊂ s[x←⍋c]
Ala'a
Post by Ala'a Mohammad
Hi,
Another two ways, Not as compact or optimized, but generate the same output
1)
G groups, C categories, and S strings
G←(⍴∪C)⍴⊂⍬ ◊ C {G[⍺]←⊂(⊃G[⍺]),⊂⍵}¨S ◊ G
I forgot how to suppress the middle output
or in a function
∇ groups ← categories group items
groups ← (⍴∪categories)⍴⊂⍬
categories {groups[⍺]←⊂(⊃groups[⍺]),⊂⍵}¨ items
2)
(1+C[x]) ⊂ S[(⍳⍴C)[x←⍋C]]
Best wishes,
Ala'a
Post by Louis de Forcrand
Is it important that they be grouped in the order specified by the key?
(⊂[1]C∘.=∪C)/¨⊂S
(⊂[1]C∘.=U[⍋U←∪C])/¨⊂S
In addition, the categories don’t have to be numbers.
Note that Dyalog’s (dyadic) key function is equivalent to this, with L being
L¨(⊂[1]C∘.=∪C)/¨⊂S
Cheers,
Louis
strings ← 'foo' 'bar' 'abc' 'def' 'ghi' 'jkl'
categories ← 1 1 0 2 1 0
I now need to group these strings according to category. In other words,
categories X strings
┏→━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃┏→━━━━━━━━━━┓ ┏→━━━━━━━━━━━━━━━━┓ ┏→━━━━┓┃
┃┃"abc" "jkl"┃ ┃"foo" "bar" "hgi"┃ ┃"def"┃┃
┃┗∊━━━━━━━━━━┛ ┗∊━━━━━━━━━━━━━━━━┛ ┗∊━━━━┛┃
┗∊∊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
What is the best way to solve this?
Continue reading on narkive:
Loading...