数组按连续顺序搜索多个值

时间:2018-05-01 18:23:53

标签: php arrays

获取给定的数组:

// Original
array:14 [
  0 => "hello"
  1 => "i"
  2 => "like"
  3 => "cats"
  4 => "they're"
  5 => "cute"
  6 => "and"
  7 => "cuddly"
  8 => "you"
  9 => "know"
  10 => "well"
  11 => "i"
  12 => "love"
  13 => "cats"
]

// Sliced
array:6 [
  0 => "like"
  1 => "cats"
  2 => "they're"
  3 => "cute"
  4 => "and"
  5 => "cuddly"
]

我想检查original数组中的sliced值并检索其原始密钥。这必须仅在连续值匹配时发生。

最终,像:

return array_keys_from_consec_values($original, $sliced);

// Result
array:14 [
  0 => 2
  1 => 3
  2 => 4
  3 => 5
  4 => 6
  5 => 7
]

备注

sliced不是在array_slice()数组上使用original的结果。否则我会使用该功能并使用保留键参数。

想要避免含糊不清。例如,array_search的简单cats将返回键3,但13也存在。哪个可能会关闭该功能。

如果sliced中没有任何original值(按顺序),则应返回空数组。失败的sliced数组示例:

// Sliced
array:6 [
  0 => "like"
  1 => "cats"
  2 => "they're"
  3 => "cut3"
  4 => "and"
  5 => "cuddly"
]

任何建议,都要考虑到速度......

3 个答案:

答案 0 :(得分:1)

根据我的理解,您希望根据$original中的值从$slice数组中获取索引,您可以使用array_flip()array_unique()函数:

function array_keys_from_consec_values($original, $slice){
    // Get rid of duplicates and flip the keys with the values
    $index = array_unique($original);
    $index = array_flip($index);

    $result = [];

    // Loop through the slice
    foreach($slice as $key => $value){
        // Check if the value exists in the indexed array
        if(!isset($index[$value])){
            // Return an empty array
            return array();
        }
        // And get the key from the flipped array
        $result[$key] = $index[$value];
    }

    return $result;
}

var_dump(array_keys_from_consec_values($original, $slice));

这将给出:

array (size=6)
  0 => int 2
  1 => int 3
  2 => int 4
  3 => int 5
  4 => int 6
  5 => int 7

答案 1 :(得分:1)

这适用于您的示例数据,可能还不错:

$r = array_keys(array_unique(array_intersect($o, $s)));

如果没有,因为你有一个切片:

if(($k = array_search($s[0], $o)) === false ||
   array_values($r = array_slice($o, $k, count($s), true)) != $s) {
    $r = [];
}
  • 从切片的第一个值
  • 中查找原始的第一个键
  • 从原始切片(保留键)切片并与切片
  • 进行比较

对于您的示例,这会产生:

Array
(
    [2] => like
    [3] => cats
    [4] => they're
    [5] => cute
    [6] => and
    [7] => cuddly
)

我想看到你想获得钥匙的事实:

$r = array_values(array_flip($r));

如果切片是原始切片的实际array_slice,则将true作为第四个参数传递以保留切片。

答案 2 :(得分:0)

努力的人,我承认这个请求有点难以解释 - 所以没有得到我正在寻找的东西。我意识到我想要的基本上是array_search,当连续发现针时会返回多个键。我已经完成了自己的功能:

/**
 * Search for consecutive needles in haystack and return the corresponding keys.
 *
 * @param array $needles => Array values.
 * @param array $haystack => Array to search.
 * @param int $searchDirection => [0] (forwards) | [1] (backwards).
 * @return array
 */
function array_search_all_consec(array $needles, array $haystack, $searchDirection = 0)
{
    $needlesInScope = array_values($needles); // Keys not relevant, reset them.
    $haystackInScope = $haystack;

    if (in_array(reset($needlesInScope), $keys = array_keys($haystackInScope))) {
        $needlesLength = count($needlesInScope);

        foreach (($searchDirection == 0 ? $keys : array_reverse($keys)) as $offset) {
            $length = $offset + $needlesLength;
            $sliced = array_slice($haystackInScope, $offset, $length);

            if (empty(array_diff_assoc($needlesInScope, $sliced))) {
                return range($offset, $length - 1);
            }
        }
    }

    return [];
}

测试1

$o = [
    0 => "hello",
    1 => "i",
    2 => "like",
    3 => "cats",
    4 => "they",
    5 => "cute",
    6 => "and",
    7 => "cuddly",
    8 => "you",
    9 => "know",
    10 => "well",
    11 => "i",
    12 => "love",
    13 => "cats",
];

$s = [
    "i",
    "love",
    "cats",
];

return array_search_all_consec($s, $o);

// Result
array(3) {
  [0] =>
  int(11)
  [1] =>
  int(12)
  [2] =>
  int(13)
}

测试2

$s = [
    "i",
    "like",
    "cats",
];

return array_search_all_consec($s, $o);

// Result
array(3) {
  [0] =>
  int(1)
  [1] =>
  int(2)
  [2] =>
  int(3)
}

测试3

$s = [
    "i",
    "lov3",
    "cats",
];

return array_search_all_consec($s, $o);

// Result
array(0) {
}

测试4

$s = [
    "cats",
    "i",
    "love",
];

return array_search_all_consec($s, $o);

// Result
array(0) {
}

测试5

$s = [
    "i",
    "love",
    "cats",
    "blah",
];

return array_search_all_consec($s, $o);

// Result
array(0) {
}

<小时/> 所以你有它。如果有人能提高功能的效率,请做出贡献!