从PHP中的数组中删除几乎重复的值

时间:2011-08-13 09:17:27

标签: php arrays duplicate-data

需要帮助!

我有一个数组,其中值重复但不完全,

somestring ='abcd-abcd-123', someOTHERstring223 ='abcsd - adsf_12ds'

Array
        (
            [0] => somestring
            [1] => somestring-(don't know the delimiter)core
            [2] => somestring_(don't know the delimiter)-(don't know the delimiter)somethingelse
            [3] => someOTHERstring223
            [4] => someOTHERstring223_junkstring
            [5] => someOTHERstring223OTHERSTRING-somethingNEW

)

我想要的结果是

somestring
someOTHERstring223

我只想要最短的值,导致somestring,somestring-(不知道分隔符)核心,somestring_(不知道分隔符) - (不知道分隔符)somethingelse是相同的 因为他们都是从一些东西开始的。

对不起大家,我没有问正确的问题。

我想出了答案,但我不知道它是否最有效,

$coLL = array('somestring',"somestring-(don't know the delimiter)core","somestring_(don't know the delimiter)-(don't know the delimiter)somethingelse"
        ,"someOTHERstring223",'someOTHERstring223_junkstring','someOTHERstring223OTHERSTRING-somethingNEW');
    $coLL2 = $coLL;
    foreach($coLL as $coLLK=>$coLLV){  
        $flength = strlen($coLLV);
        foreach($coLL2 as $coLL2K=>$coLL2V){            
            if(strcmp($coLLV, $coLL2V) < 0){
                if(strlen($coLL2V)-$flength > 3){                    
                    unset($coLL2[$coLL2K]);
                }
            }        
        }        
    }

我设置此限制器if(strlen($ coLL2V) - $ flength&gt; 3) 因为如果somestring1出现或者somestring12或somestring123它们是唯一的并且它们与某些字符串不匹配。

感谢大家的回答。

5 个答案:

答案 0 :(得分:1)

这应该这样做:

<?php

    $array = array('apple','apple-core','apple-core-something','orange','orange-core','orange-core-someting');
    $result = array();
    foreach ($array as $entry) {
        $entry = explode('-',$entry);
        if (!in_array($entry[0],$result)) {
            $result[] = $entry[0];
        }
    }

    print_r($result);

?>

Working Example

答案 1 :(得分:1)

其他答案都假设-或其他一些令牌可以界定您的最短字符串。要在没有任何分隔符的情况下执行您想要的操作,您可以使用this code

之类的内容
$yourArray = Array(
    0 => "apple",
    1 => "apple-core",
    2 => "apple-core-something",
    3 => "orange",
    4 => "orange-dot",
    5 => "orange-dot-something",
) ;
$resultArray = Array() ;

foreach($yourArray as $test) {
    if(strlen($test)==0) continue(1) ;        // Drop 0 length items.
    foreach($resultArray as $rkey => $rval) {
        if(strpos($test, $rval)===0) {        // If $test starts with $rval
            continue(2) ;                     // Continue outer foreach
        } elseif(strpos($rval, $test)===0) {  // If $rval starts with $test
            unset($resultArray[$rkey]) ;      // No longer shortest unique
            continue(1) ;                     // Continue inner foreach (and add $test)
        }
    }
    $resultArray[] = $test ;
}

var_dump($resultArray) ;
// array(2) {
//   [0]=>
//   string(5) "apple"
//   [1]=>
//   string(6) "orange"
// }

答案 2 :(得分:0)

    $store = array();

    foreach($data as $fruit) $store[] = array_shift(explode('-',$fruit));



print_r($store);

此处$ data是您在上面发布的数组

答案 3 :(得分:0)

解决你的问题:

  1. 将每个值规范化为仅包含您要查找的重复项(strtokDocs)的值。
  2. 从数组中删除重复项(array_uniqueDocs)。
  3. Demo

    function normalize($v)
    {
       return strtok($v, '-_');
    }
    
    $normalized = array_map('normalize', $data);
    
    $unique = array_unique($normalized);
    

    结果:

    array(3) {
      [0]=>
      string(10) "somestring"
      [3]=>
      string(18) "someOTHERstring223"
      [5]=>
      string(29) "someOTHERstring223OTHERSTRING"
    }
    

    实际上,您为列表中的每个条目构建了一个哈希值。散列表示原始值的比较值。那么哈希是唯一的(你实际上只想要哈希)。

    您需要的是一个满足您需求的哈希函数。在上面的示例中,哈希函数为normalize

    如果结果不符合您的需求,您需要采用哈希函数。我选择了strtok,因为它似乎适合你的(原创)案例。但是,如果查找分隔符变得更复杂,您可能会寻找正则表达式来指定分隔符,例如preg_splitDocspreg_replaceDocs

    但是,为了使用正则表达式,您必须知道您的分隔符是什么,因为基本上您遵循策略来填充字符串以构建哈希。没有明确指定的分隔符,只会尝试错误。

答案 4 :(得分:0)

foreach($a as $k=>$v) {
    foreach($a as $k2=>$v2) {
        if ($k2 == $k)
            break;
        if ($v == substr($v2, 0, strlen($v))) {
            unset($a[$k2]);
            break;
        }
        if ($v2 == substr($v, 0, strlen($v2))) {
            unset($a[$k]);
            break;
        }
    }
}

注意:我的解决方案只删除数组中有元素的元素,该元素是元素的精确前缀。您更新的问题没有解决方案,因为您必须知道分隔符是什么。