2010-06-02 55 views
1

所以,我有三個數組是這樣的:如何在php中編寫高效的黑名單過濾函數?

[items] => Array 
      ([0] => Array 
        ( 
        [id] => someid 
        [title] => sometitle 
        [author] => someauthor 
        ... 
       ) 
       ... 
      ) 

,並與逗號分隔的單詞串黑名單:

$blacklist = "some,words,to,blacklist"; 

現在我需要,以配合這些話(因爲他們可以一個)id,標題作者並相應地顯示結果。

我在想一個函數是這樣的:

$pattern = '('.strtr($blacklist, ",", "|").')'; // should return (some|words|etc) 

    foreach ($items as $item) { 
      if (!preg_match($pattern,$item['id']) || !preg_match($pattern,$item['title']) || !preg_match($pattern,$item['author'])) 
       { 
        // show item 
       } 
    } 

,我不知道這是否是過濾陣列的最有效的方式還是應該使用帶有strpos()filter_var的東西FILTER_VALIDATE_REGEXP ...

請注意,此功能每3個陣列重複一次。但是,每個陣列不會包含超過50個項目。

+0

您可以將id,title和author加入到一個字符串中(可能帶有一個divider char)。如果這真的會導致性能差異,我不能說。 =) – Jens 2010-06-02 14:16:42

+0

作弊的方式將寫入文件的東西,並使用「fgrep -f」 – barrycarter 2010-06-02 14:29:34

+0

哦,這讓我想:如果我將所有**的身份,標題和作者加入一個大字符串和然後在循環之前進行第一次檢查,並在循環**中僅進行第二次檢查**如果第一次是真的? – achairapart 2010-06-02 14:29:57

回答

3

你的不錯。我通常會使用strpos這樣的事情......

 


$items = filter($foo['items'], array('some','words','to','blacklist')); 

function filter($items, $blacklist) { 

    $filtered = array(); 

    foreach($items as $item) { 
     foreach($item as $key => $value) { 
      $pass = true; 
      foreach($blacklist as $filter) { 
       $pass = strpos($value, $filter) === false; 
       if(!$pass) break; 
      } 
      if($pass) $filtered[] = clone($item); 
     } 
    } 

    return $filtered; 
} 
 

要添加更多的複雜性,你可以標記化你用空白檢查字符串。然後代碼將變爲:

 

function filter($items, $blacklist) { 

    $filtered = array(); 

    foreach($items as $item) { 
     foreach($item as $key => $value) { 
      $pass = true; 
      foreach(explode(' ', $value) as $word) { 
       $pass = !in_array($word, $blacklist); 
       if(!$pass) break; 
      } 
      if($pass) $filtered[] = clone($item); 
     } 
    } 

    return $filtered; 
}