简体   繁体   English

如何检查两个字符串是否具有相同的开头?

[英]How to check if two strings have the same beginning?

Considering I have one-dimensional ordered array of strings:考虑到我有字符串的一维有序数组:

$arr = [
    'Something else',
    'This is option: one',
    'This is option: two',
    'This is option: 😜',
    'This is second option: 2',
    'This is second option: 3'
];

I would like to turn it into two-dimensional array, having the common beginning as the key.我想把它变成二维数组,以共同的开头为键。 For example:例如:

$target = [
    'Something else',
    'This is option:' => [
        'one',
        'two',
        '😜'
    ],
    'This is second option:' => [
        '2',
        '3'
    ]
];

It sounds simple, but I have gone completely blank.这听起来很简单,但我已经完全空白了。

function convertArr(array $src): array {
    $prevString = null;
    $newArray = [];
    foreach ($src as $string) {
        if ($prevString) {
            // stuck here
        }
        $prevString = $string;
    }
    return $newArray;
}

Pre-made fiddle: https://3v4l.org/eqGDc预制小提琴: https://3v4l.org/eqGDc

How can I check if two strings start with the same words, without having to loop on each letter?如何检查两个字符串是否以相同的单词开头,而不必循环每个字母?

As of now I have written this overly-complicated function, but I wonder if there is a simpler way:到目前为止我已经写了这个过于复杂的function,但我想知道是否有更简单的方法:

function convertArr(array $src): array {
    $prevString = null;
    $newArray = [];

    $size = count($src);
    for ($i = 0; $i < $size; $i++) {
        if (!$prevString || strpos($src[$i], $prevString) !== 0) {
            if ($i == $size - 1) {
                $newArray[] = $src[$i];
                break;
            }
            $nowWords = explode(' ', $src[$i]);
            $nextWords = explode(' ', $src[$i + 1]);
            foreach ($nowWords as $k => $v) {
                if ($v != $nextWords[$k]) {
                    break;
                }
            }
            if ($k) {
                $prevString = implode(' ', array_splice($nowWords, 0, $k));
                $newArray[$prevString][] = implode(' ', $nowWords);
            }
        } else {
            $newArray[$prevString][] = trim(substr($src[$i], strlen($prevString)));
        }
    }
    return $newArray;
}

I haven't got a complete solution, but maybe you can use this as a starting point: The following gets you the longest common starting sequence for the strings in an array of length 2:我没有一个完整的解决方案,但也许您可以以此为起点:以下为您提供长度为 2 的数组中字符串的最长公共起始序列:

var s=["This is option: one","This is option: two"]; 
var same=s.join('|').match(/(.*)(.*?)\|\1.*/)[1];
// same="This is option: "

In same you will find the longest possible beginning of the two strings in array s . same ,您会在数组s中找到两个字符串的最长可能开头。 I achieve this by using a regular expression with a greedy and a non-greedy wildcard group and forcing the first group to be repeated.我通过使用带有贪婪和非贪婪通配符组的正则表达式并强制重复第一组来实现这一点。

You could apply this method on slice() -d short arrays of your original sorted input array and monitor whether same stays the same for a number of these sub-arrays.您可以在原始排序输入数组的slice() -d short arrays 上应用此方法,并监视这些子数组的数量是否same You can then perform your intended grouping operation on sections with the same same .然后,您可以对具有same .

[[ Sorry, I just realized I coded this in JavaScript and you wanted PHP - but the idea is so simple you can translate that easily into PHP yourself. [[对不起,我刚刚意识到我在 JavaScript 中编写了这个代码,而你想要 PHP - 但这个想法非常简单,你可以自己轻松地将其翻译成 PHP。 ]] ]]

Edit编辑

When looking at the question and expected result again it seems to me, that what the OP really wants is to combine elements with similar parts before the colon (:) into a common sub-array.当再次查看问题和预期结果时,在我看来,OP真正想要的是将冒号 (:) 之前具有相似部分的元素组合成一个公共子数组。 This can be done with the following code:这可以通过以下代码完成:

$arr = [
    'Is there anything new and',
    'Something old',
    'This is option: one',
    'This is option: two',
    'This is option: 😜',
    'This is second option: 2',
    'This is second option: 3',
    'Abc: def',
    'Abc: ghi',
    'the same line',
    'the same words'
];
foreach($arr as $v) {
 $t=array_reverse(explode(':',$v));
 $target[isset($t[1])?trim($t[1]):0][]=trim($t[0]);
}
print_r($target)

output: output:

Array
(
    [0] => Array
        (
            [0] => Is there anything new and
            [1] => Something old
            [2] => the same line
            [3] => the same words
        )

    [This is option] => Array
        (
            [0] => one
            [1] => two
            [2] => 😜
        )

    [This is second option] => Array
        (
            [0] => 2
            [1] => 3
        )

    [Abc] => Array
        (
            [0] => def
            [1] => ghi
        )

)

See a demo here https://rextester.com/JMB6676在此处查看演示https://rextester.com/JMB6676

This might do the job:这可能会完成这项工作:

function convertArray(array $values): array
{
    $newArray = [];
    foreach ($values as $value) {
        if (stripos($value, ':') !== false) {
            $key = strtok($value, ':');
            $newArray[$key][] = trim(substr($value, stripos($value, ':') + 1));
        }
    }

    return $newArray;
}

Essentially, based on the format of your array of strings, as long as each string only has one ":" character followed by the option value, this should work well enough.本质上,根据字符串数组的格式,只要每个字符串只有一个“:”字符后跟选项值,这应该可以很好地工作。

I'm sure there will be a more advanced and more fail-safe solution but this may be a start.我相信会有更先进和更安全的解决方案,但这可能是一个开始。

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

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