2016-08-26 2 views
1

J'ai ce code où je veux obtenir les mots les plus fréquents d'un texte. J'utilise plusieurs fonctions de tableau telles que str_word_count(), array_count_values(), et enfin array_filter(). Voici le code comme suit:php array_filter fonctionne dans les fonctions mais pas dans une classe comme méthode

<?php 
/*Get the most frequent words with PHP*/ 

/*1. Assign the text to a variable*/ 
$text='NOT long ago, many parents wondered at what age they should give their child full access to the car keys. Nowadays, parents face a trickier question: At what age should a child own a smartphone? 

The smartphone, after all, is the key to unfettered access to the internet and the many benefits and dangers that come with it. But unlike driving a car, which is legal in some states starting at the age of 16, there is no legal guideline for a parent to determine when a child may be ready for a smartphone. 

The topic is being increasingly debated as children get smartphones at an ever younger age. On average, children are getting their first smartphones around age 10, according to the research firm Influence Central, down from age 12 in 2012. For some children, smartphone ownership starts even sooner — including second graders as young as 7, according to internet safety experts.';  
echo $text; 
/*2. Set to lowercase*/ 
$text = strtolower($text); 
/*3. Separate the text into words, into an array. Accept foreign ascii characters*/ 
$words = str_word_count($text,1,'áâæàåãäçéêèëíîìïñóôòøõöœúûùüÿ¿¡'); 
echo '<br><hr><h3>Words:</h3>'; 
if(is_array($words)){echo '<p>$words is indeed an array</p>';} 
var_dump($words); 
/*3. Get each word's occurrences'*/ 
$words = array_count_values($words); 
echo '<br><hr><h3>Words occurrences:</h3>'; 
var_dump($words); 
/*4. Order according to occurrences*/ 
echo '<br><hr>'; 
arsort($words); 
var_dump($words); 
echo '<br><hr>'; 
/*5. Defining the stopwords*/ 
//Stopwords: 
$stopwords = ['the','to','it','is','a','at','for','as']; 
/*6. Filter out the stopwords and those words with a frequence not more than 2 occurrences*/ 
$palabras = array_filter($words, function($word,$index)use($stopwords){ 
    if(!in_array($index,$stopwords)){ 
     if($word>2){ 
      return true; 
     } 
    } 
},ARRAY_FILTER_USE_BOTH); 

echo '<p>Now the most frequent words are (without the stop words):</p>'; 
var_dump($palabras); 
?> 

Il fonctionne très bien. Maintenant, je veux passer ce code dans une classe.

Voici le code de la classe et instanciation:

<?php 
/*Class to get the most frequent words from a text*/ 
namespace Models\Helpers\TextMining; 

class Word 
{ 
    protected $text; 
    protected $words=[]; 
    protected $filtered_words=[]; 
    protected $stopwords = []; 
    protected $lang; 
    protected $active; 
    protected $ascii = 'áâæàåãäçéêèëíîìïñóôòøõöœúûùüÿ¿¡'; 

    public function __construct($text,$lang = 'es',$active = true) 
    { 
     $this->text = strtolower($text); 
     $this->words = str_word_count($this->text,1,$this->ascii); 
     $this->lang = $lang; 
     $this->active = $active; 
     $this->stopwords = ['the','to','it','is','a','at','for','as']; 
     arsort(array_count_values($this->words)); 
    } 

    /*Show stopwords*/ 
    public function getStopwords(){ 
     return $this->stopwords; 
    } 
    /*Show the words from the text*/ 
    public function getWords() 
    { 
     return $this->words; 
    } 

    /*Filter out the stopwords from the text and those words with an occurrence not greater than 2*/ 
    public function applyStopwords2text() 
    { 
     $stopwords = $this->getStopwords(); 
     $words = $this->getWords(); 

     $palabras = array_filter($words, function($word,$index)use($stopwords){ 
      if(!in_array($index,$stopwords)){ 
       if($word>2){ 
        return true; 
       } 
      } 
     },ARRAY_FILTER_USE_BOTH); 

     $this->filtered_words = $palabras; 
     return $palabras; 
    } 
} 

/***************/ 
    $text='NOT long ago, many parents wondered at what age they should give their child full access to the car keys. Nowadays, parents face a trickier question: At what age should a child own a smartphone? 

The smartphone, after all, is the key to unfettered access to the internet and the many benefits and dangers that come with it. But unlike driving a car, which is legal in some states starting at the age of 16, there is no legal guideline for a parent to determine when a child may be ready for a smartphone. 

The topic is being increasingly debated as children get smartphones at an ever younger age. On average, children are getting their first smartphones around age 10, according to the research firm Influence Central, down from age 12 in 2012. For some children, smartphone ownership starts even sooner — including second graders as young as 7, according to internet safety experts.'; 

    $word = new Word($text,'es',true); 
    $stopwords = $word->getStopwords(); 
    var_dump($stopwords); 
    //var_dump($word); 
    //die(); 
    $words = $word->applyStopwords2text(); 

    var_dump($words); 


?> 

Le problème est avec la fonction array_filter(), parce que je reçois un tableau vide. Rien n'est stocké dans la propriété protected $filtered_words=[]; lors de l'utilisation de la même fonction array_filter(). Pourquoi? Comment résoudre ce problème?

Répondre

2

Votre problème est dans votre constructeur - vous n'avez pas fait que le code fasse la même chose que dans la version autonome.

Dans la dernière ligne:

arsort(array_count_values($this->words)); 

Le résultat de array_count_values n'est affecté à quoi que ce soit, donc arsort trie la matrice temporaire, puis ne sauve pas.

Changer votre constructeur à:

public function __construct($text,$lang = 'es',$active = true) 
{ 
    $this->text = strtolower($text); 
    $this->words = str_word_count($this->text,1,$this->ascii); 
    $this->lang = $lang; 
    $this->active = $active; 
    $this->stopwords = ['the','to','it','is','a','at','for','as']; 
    $this->words = array_count_values($this->words); 
    arsort($this->words); 
} 

Ensuite, il correspondra à la version non-oop du code.

3

Il semble que vous ayez fait une petite erreur dans votre méthode constructeur. Essayez ceci:

public function __construct($text,$lang = 'es',$active = true) 
{ 
    $this->text = strtolower($text); 
    $this->words = str_word_count($this->text,1,$this->ascii); 
    $this->lang = $lang; 
    $this->active = $active; 
    $this->stopwords = ['the','to','it','is','a','at','for','as']; 
    $this->words = array_count_values($this->words); 
    arsort($this->words); 
} 

Comme vous le voyez, le résultat de array_count_values n'est pas affecté à $this->$words, donc vous avez encore votre tableau vieux mots lorsque vous appelez la fonction de filtre.