user6364857 user6364857 - 6 months ago 11
PHP Question

Divide words depending on first character

I have a paragraph, What i want to group each words depending on the first character and sort the group by other character.

Sample text:

$text = "Why end might ask civil again spoil. She dinner she our horses depend. Remember at children by reserved to vicinity. In affronting unreserved delightful simplicity ye. Law own advantage furniture continual sweetness bed agreeable perpetual. Oh song well four only head busy it. Afford son she had lively living. Tastes lovers myself too formal season our valley boy. Lived it their their walls might to by young.";


Expected result for the first sentence-

Why end might ask civil again spoil

a => again, ask
c => civil
e => end
m => might
s => spoil
w => Why

Answer

So many ways to do it.... I just chose one I find slightly more interesting (than just "gimme script" ;-))

<?php
// see http://docs.php.net/splheap
class StrcasecmpHeap extends SplHeap {
    protected function compare ($a,$b) { return strcasecmp($b,$a); }
}
$text = "Why end might ask civil again spoil. She dinner she our horses depend. Remember at children by reserved to vicinity. In affronting unreserved delightful simplicity ye. Law own advantage furniture continual sweetness bed agreeable perpetual. Oh song well four only head busy it. Afford son she had lively living. Tastes lovers myself too formal season our valley boy. Lived it their their walls might to by young.";

// create
$result = [];
// see http://docs.php.net/preg_split
foreach( preg_split('![^a-zA-Z]+!', $text, -1, PREG_SPLIT_NO_EMPTY) as $word ) {
    $char = strtolower($word[0]);
    if ( !isset($result[$char]) ) {
        $result[$char] = new StrcasecmpHeap;
    }
    $result[$char]->insert($word);
}

// print
foreach( $result as $char=>$list ) {
    echo "--- $char ---", PHP_EOL;
    foreach($list as $word ) {
        echo ' ', $word, PHP_EOL;
    }
}

This will keep doublets like e.g.

--- s ---
season
She
she
she
simplicity

or

<?php
$text = "Why end might ask civil again spoil. She dinner she our horses depend. Remember at children by reserved to vicinity. In affronting unreserved delightful simplicity ye. Law own advantage furniture continual sweetness bed agreeable perpetual. Oh song well four only head busy it. Afford son she had lively living. Tastes lovers myself too formal season our valley boy. Lived it their their walls might to by young.";

// build
$result = [];
foreach( preg_split('![^a-zA-Z]+!', $text, -1, PREG_SPLIT_NO_EMPTY) as $word ) {
    // here goes the case-sensitivity; it's all lower-case from now on....
    $word = strtolower($word);
    $char = $word[0];
    // not storing as the element's value but the key
    // takes care of doublets
    $result[$char][$word] = true;
}

// get keys & sort
$result = array_map(
    function($e) {
        // remember? The actual words have been stored as the keys
        $e = array_keys($e);
        usort($e, 'strcasecmp');
        return $e;
    },
    $result
);


// print
var_export($result);