繁体   English   中英

如何过滤字符串数组以删除作为其他元素前缀的元素?

[英]How can I filter an array of strings to remove elements that are prefixes of other elements?

如果我有一个字符串数组,如何通过过滤掉该数组中其他字符串前缀的任何字符串来减少它?

例如,如果我从以下数组开始:

$array = array('123', '234', '1234', '2345', '123456', '345', '1', 
               '12', 'six', 'one/two/three','six/seven','one/two');

我试图以这个数组结束:

$new_array = array('123456', '2345', '345', 'six/seven', 'one/two/three');

因为'12345'与开始'1234' ,其与启动'123' ,等等。

我想我需要从数组中循环字符串,如果字符串长度较大且以先前的字符串开头,则将旧的字符串替换为新的字符串。

我想使用此代码

foreach ($array as $string) { 
    // compare with previous strings
    $new_array[] = $string; // replace prefixes of $string
}

但我不知道如何进行比较。 我该怎么做?

看起来您想要执行的操作是将数组分组为一组字符串,以扩展该组中的其他字符串,然后从每个组中选择最长的字符串。 数组中的组

$old_array = array('123','234','1234','2345','123456','345','1','12');

将会

1, 12, 123, 1234, 123456
234, 2345
345

这是执行此操作的一种方法:

foreach ($old_array as $old) {

    // set a flag to indicate whether the value has already been added
    $matched = false;

    // loop over the new values by reference
    foreach ($new_array as &$new) {

        if ($new == $old) {  // this should prevent duplicate values from being added
            $matched = true; 

        } elseif ((strlen($old) > strlen($new)) && strpos($old, $new) === 0) {
            // if the old string starts with the new string, replace the value
            $new = $old;
            $matched = true;

        } elseif ((strlen($new) > strlen($old)) && strpos($new, $old) === 0) {
            // if the new string starts with the old string don't replace it and don't add it
            $matched = true;
        }
    }
    unset($new); // unset the reference

    if (!$matched) {
        // if no matching strings were found, add the string
        $new_array[] = $old;
    }
}

再次查看之后,如果首先使用SORT_STRING对输入数组进行排序,则可能会简单得多。

sort($old_array, SORT_STRING);
$old_array[] = null;  // append a null to force comparison of the last item
foreach ($old_array as $value) {
    if (isset($current) && !(strpos($value, $current) === 0)) {
        $new_array[] = $current;
    }
    $current = $value;
}

根据您的帖子,我收集到您想要遍历每个元素(从最高到最低)的信息,并查看当前条目是否包含在最近发生的条目中。

尝试下面的代码,至少它会输出您想要的内容。

$array = array('123','234','1234','2345','123456','345','1','12');

//First sort the array to get all of the bigger ones at the start
rsort($array);

//Then put the largest one in to the array, as you clearly want to start with something
$newArray[] = $array[0];

//Then loop through each value
foreach($array as $key => $value){

    //If the key is 0, then skip it, to avoid duplication
    if($key == 0){
        continue;
    }

    //Get the last entry of $newArray
    $lastEntry = end($newArray);

    //See if the current string is contained in the most recently saved one
    if(strpos($lastEntry, $value) !== false){

        //If so, add it to the new array
        $newArray[] = $value;
    }
}

//Just use the new Array instead of replacing the old one
var_dump($newArray);

//Uncomment this if you want to replace it
//$array = $newArray;

我已经评论了其中的每个部分,因此,如果您有其他问题,可以随时在评论中提出,以查看每个步骤的作用。

我想这就是你想要的。 rsort($new_array);

将数字从最高到最低排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM