문제

How could functions similar to PHP's explode and implode be implemented with APL?

I tried to work it out myself and came up with a solution which I'm posting below. I'd like to see other ways that this might be solved.

도움이 되었습니까?

해결책

Pé, the quest for "short" and/or "elegant" solutions to standard-problems in APL is older than PHP and even older than new terminology, such as "eplode", "implode" (I think - but I must admit I do not know how old these terms really are...). Anyway, the early APL guys used the term "idiom" for such "solutions to standard problems that fit in one line of APL". And for some reason, the Finns were especially creative and even started producing a list of these in order to make it easy for newbies. And I find this stuff still useful after 20yrs of doing APL. It is called "FinnAPL" - the Finnish APL idiom library and you can browse it here: http://aplwiki.com/FinnAplIdiomLibrary (BTW, the whole APL-Wiki might be interesting to read...)

You may, however, need to be creative with your wording in order to find solutions ;) And one warning: FinnAPL only works with "classic" (non-nested) data-structures (nested matrices came with "APL2" which is standard these days), so some of the ways they handle data might no longer be "state-of-the-art". (i.e. back in the "old times", CAT BIRD and DOG would have been represented as a 3x4 array, so "implode" of string-array was a simple as ,array,delimeter (but you then had the challenge to remove blanks which were inserted for padding.

Anyway, I'm not sure why I wrote all this - just a few thoughts which came to mind when thinking about my start with APL ;-)

Ok, let me also look at the question. When your delimeter is a single character the APL2ish-idiomatic way of handling this would be something like this:

⎕ml←3    ⍝ "migration-level" (only Dyalog APL) to ensure APL2-compatibility
s←' '
A←s,'BIRD',s,'CAT',s,'DOG'     ⍝ note that delimeter also used as 1st char!
exploded_string←1↓¨(+\A=s)⊂A   ⍝ explode
imploded←∊s,¨exploded_string
A≡imploded                     ⍝ test for successfull round-trip should return 1

다른 팁

Explode:

Given the following text string and delimiter string:

F←'CAT BIRD DOG'
B←' '

Explode can be accomplished as follows:

S←⍴,B
P←(⊃~∨/(-S-⍳S)⌽¨S⍴⊂B⍷F)⊂F
P[2] ⍝ returns BIRD

Limitations:

PHP's explode function returns a null array value when two delimiters are adjacent to each other. The code above simply ignores that and treats the two delimiters as if they were one.

The code above also does nothing to handle overlapping delimiters. This is most likely to occur if repeated characters are used for the delimiter. For example:

F←'CATaaaBIRDaaDOG'
B←'aa'
S←⍴,B
P←(⊃~∨/(-S-⍳S)⌽¨S⍴⊂B⍷F)⊂F
P ⍝ returns CAT BIRD DOG

However, the expected result would be CAT aBIRD DOG because it doesn't recognize 'aaa' as the delimiter followed by 'a.' Rather, it treats it as two overlapping delimiters, which end up functioning as a single delimiter. Another example would be 'tat' as the delimiter, in which case, any occurence in the string of 'tatat' would have the same problem.

Overlapping Delimiters:

I have an alternative for the possibility of a single overlap:

S←⍴,B
A←B⍷F
A←(2×A)>⊃+/(-S-⍳S)⌽¨S⍴⊂A
P←(⊃~∨/(-S-⍳S)⌽¨S⍴⊂A)⊂F

The third line of code eliminates any string positions that occur within a distance of S-1 characters from any delimiter position before it. As I said, this only solves the problem for a single overlap. If there are two or more overlaps, the first is recognized as a delimiter, and all the rest are ignored. Here's an example of two overlaps:

F←'CATtatatatBIRDtatDOG'
B←'tat'
S←⍴,B
A←B⍷F
A←(2×A)>⊃+/(-S-⍳S)⌽¨S⍴⊂A
P←(⊃~∨/(-S-⍳S)⌽¨S⍴⊂A)⊂F
P ⍝ returns CAT atatBIRD DOG

The expected result was 'CAT a BIRD DOG,' but it is unable to recognize the final 'tat' as a delimiter because of the overlap. Such a situation would be rare except when repeated characters are used. If the delimiter is 'aa', then 'aaaa' would be considered a double overlap, and only the first delimiter would be recognized.

Implode:

Much simpler:

P←'CAT' 'BIRD' 'DOG'
B←'-'
(⍴,B)↓∊B,¨P

It returns 'CAT-BIRD-DOG' as expected.

An interesting alternative for implode can be accomplished with reduction:

      p←'cat' 'bird' 'dog'
      ↑{⍺,'-',⍵}/p
cat-bird-dog

This technique does not need to explicitly reference the shape of the delimiter.

And an interesting alternative to explode can be done with n-wise reduction:

      f←'CATtatBIRDtatDOG'
      b←'tat'
      b{(~(-⍴⍵)↑(⍴⍺)∨/⍺⍷⍵)⊂⍵}f
 CAT  BIRD  DOG 

Explode() function divides a string into an array, but implode function() returns or combine a string from the elements of an array.

Example explode:

<?php
$str = "india australia";
$str = explode(" ", $string); //here string delimeter is space
Ouput:
$str[0] = india ;
$str[1] = australia ;
?>

implode:

<?php
$array = array('india','australia','srilanka');
$comma_separated = implode(",",$array);  //here comma is separated
echo $comma_separated;
?>
Output:
indiaaustraliasrilanka
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top