1

我有两个数组,如下所示:

$arr1 = ("stringType1AndSomeRandomStuff",
         "stringType2AndSomeRandomStuff",
         "stringType3AndSomeRandomStuff",
         "stringType1AndSomeRandomStuff",
         "stringType2AndSomeRandomStuff",
         "i don't belong here at all!",
         "stringType4AndSomeRandomStuff");

在第一个数组 ( $arr1) 中,大多数键都有某种共同的属性。在上面的示例文本中,这将是stringTypeX. 这个“共同因素”是我需要搜索的。每个字符串还具有某种额外的数据,例如AndSomeRandomStuff.

第二个数组如下所示:

$arr2 = ("stringType1" => "category1",
         "stringType2" => "category2",
         "stringType3" => "category3",
         "stringType4" => "category4");

我需要遍历每个字符串$arr1,看看它是否$arr2. 如果它与其中一个匹配,我需要来自.$arr2

我如何遍历每个字符串$arr1并确定哪些(如果有)$arr2适用?基本上,我需要遍历每个字符串并对 中的所有$arr1执行部分匹配,以找到最接近的匹配项。想到的直接解决方案是使用两个循环(外部用于所有 in和内部用于每个 in ),但是 PHP 中是否有一个函数可以获取一个字符串并查看它是否与现有数组中的任何字符串匹配?有谁知道更高效的方法来做到这一点?$arr2$arr1$arr2

4

1 回答 1

3

映射$arr1到一个函数,该函数计算到 中的键的字符串编辑距离$arr2,然后返回最接近的匹配项。看看这个 Levenshtein 距离函数。或者,您可以简单地在映射函数中进行startsWith比较。

您可能会看到如下所示的内容:

$stringEditDistanceThreshold = 5; // greater than this means rejected

// define the mapping function
function findClosestMatchingString($s) {
    $closestDistanceThusFar = $stringEditDistanceThreshold + 1;
    $closestMatchValue      = null;

    foreach ($arr2 as $key => $value) {
        $editDistance = levenshtein($key, $s);

        // exact match
        if ($editDistance == 0) {
            return $value;

        // best match thus far, update values to compare against/return
        } elseif ($editDistance < $closestDistanceThusFar) {
            $closestDistanceThusFar = $editDistance;
            $closestMatchValue      = $value;
        }
    }

    return $closestMatch; // possible to return null if threshold hasn't been met
}

// do the mapping
$matchingValues = array_map('findClosestMatchingString', $arr1);

您可能必须调整$stringEditDistanceThreshold直到您获得满意的值。或者您可以使用startsWith函数,这将大大简化findClosestMatchingString必须做的事情。

最后,这不是很有效。它实际上是一个丑陋的嵌套循环。您可能可以进行一些修剪或其他聪明的操作,但我怀疑如果数组相当小,您可能不在乎。

编辑:正如@Ohgodwhy 在下面的评论中所述,preg_grep可能会更好地为您服务。在这种情况下,您的地图函数将如下所示:

function findFirstMatchingString($s) {
    $matchingKeys = preg_grep($s, array_keys($arr2));

    if (!empty($matchingKeys) {
        // return the value of the first match
        return $arr2[$matches[0]];
    }

    return null;
}
于 2013-07-18T00:49:02.113 回答