HasWordCollection::getWordLike()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 2
eloc 8
c 1
b 1
f 0
nc 2
nop 1
dl 0
loc 15
rs 10
1
<?php
2
3
namespace CustomD\WordFinder\Traits;
4
5
use RuntimeException;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Str;
8
9
trait HasWordCollection
10
{
11
12
    /**
13
     * Database of words to choose from
14
     */
15
    protected Collection $wordsCollection;
16
17
    protected Collection $wordLengths;
18
19
20
    protected function setWordsCollection(Collection $wordsCollection): self
21
    {
22
        $this->wordsCollection = $wordsCollection
23
            ->map(
24
                function ($word) {
25
                    $charClass = resolve(config('word-finder.character_map'));
26
                    $word = (method_exists($charClass, 'mapChars')) ? $charClass->mapChars($word) : $word;
27
                    return Str::replace(" ", "", Str::upper($word));
28
                }
29
            )
30
            ->filter(
31
                fn ($word) =>  Str::length($word) >= $this->minWordLen && Str::length($word) <= $this->maxWordLen
32
            );
33
34
        $this->wordLengths = $this->wordsCollection->mapToGroups(fn($word) => [Str::length($word) => $word]);
35
36
        return $this;
37
    }
38
39
    protected function getRandomWordLength(array $exclude = []): int
40
    {
41
42
        if (count($exclude) === $this->wordLengths->keys()->count()) {
43
            return 0;
44
        }
45
46
        do {
47
            $len = $this->wordLengths->keys()->random();
48
        } while (in_array($len, $exclude));
49
50
        $available = $this->wordsCollection->filter(fn ($word) => Str::length($word) === $len)->count();
51
52
        if ($available > 0) {
53
            return $len;
54
        }
55
56
        $exclude[] = $len;
57
58
        return $this->getRandomWordLength($exclude);
59
    }
60
61
    protected function markWordUsed($word): void
62
    {
63
        $this->wordsCollection = $this->wordsCollection->reject(function ($current) use ($word) {
64
            return $current === $word;
65
        });
66
    }
67
68
    protected function getRandomWord(int $len): string
69
    {
70
        $word = $this->wordsCollection->filter(function ($word) use ($len) {
71
            return Str::length($word) === $len;
72
        })->random(1)->first();
73
74
        $this->markWordUsed($word);
75
76
        return $word;
77
    }
78
79
    protected function getWordLike(string $pattern): ?string
80
    {
81
        $pattern = Str::replace("_", ".", $pattern);
82
        $words = $this->wordsCollection->filter(function ($word) use ($pattern) {
83
            return preg_match("/^$pattern\$/i", $word);
84
        });
85
86
        if ($words->count() === 0) {
87
            return null;
88
        }
89
90
        $word = $words->random(1)->first();
91
92
        $this->markWordUsed($word);
93
        return $word;
94
    }
95
}
96