Pergunta

I'm trying to do something but I can't find any solution, I'm also having some trouble putting it into works so here is a sample code, maybe it'll be enough to demonstrate what I'm aiming for:

$input = array
(
    'who' => 'me',
    'what' => 'car',
    'more' => 'car',
    'when' => 'today',
);

Now, I want to use array_splice() to remove (and return) one element from the array:

$spliced = key(array_splice($input, 2, 1)); // I'm only interested in the key...

The above will remove and return 1 element (third argument) from $input (first argument), at offset 2 (second argument), so $spliced will hold the value more.

I'll be iterating over $input with a foreach loop, I know the key to be spliced but the problem is I don't know its numerical offset and since array_splice only accepts integers I don't know what to do.

A very dull example:

$result = array();

foreach ($input as $key => $value)
{
    if ($key == 'more')
    {
        // Remove the index "more" from $input and add it to $result.
        $result[] = key(array_splice($input, 2 /* How do I know its 2? */, 1));
    }
}

I first though of using array_search() but it's pointless since it'll return the associative index....

How do I determine the numerical offset of a associative index?

Foi útil?

Solução

Just grabbing and unsetting the value is a much better approach (and likely faster too), but anyway, you can just count along

$result = array();
$idx = 0; // init offset
foreach ($input as $key => $value)
{
    if ($key == 'more')
    {
        // Remove the index "more" from $input and add it to $result.
        $result[] = key(array_splice($input, $idx, 1));
    }
    $idx++; // count offset
}
print_R($result);
print_R($input);

gives

Array
(
    [0] => more
)
Array
(
    [who] => me
    [what] => car
    [when] => today
)

BUT Technically speaking an associative key has no numerical index. If the input array was

$input = array
(
    'who' => 'me',
    'what' => 'car',
    'more' => 'car',
    'when' => 'today',
    'foo', 'bar', 'baz'
);

then index 2 is "baz". But since array_slice accepts an offset, which is not the same as a numeric key, it uses the element found at that position in the array (in order the elements appear), which is why counting along works.

On a sidenote, with numeric keys in the array, you'd get funny results, because you are testing for equality instead of identity. Make it $key === 'more' instead to prevent 'more' getting typecasted. Since associative keys are unique you could also return after 'more' was found, because checking subsequent keys is pointless. But really:

if(array_key_exists('more', $input)) unset($input['more']);

Outras dicas

I found the solution:

$offset = array_search('more', array_keys($input)); // 2

Even with "funny" arrays, such as:

$input = array
(
    'who' => 'me',
    'what' => 'car',
    'more' => 'car',
    'when' => 'today',
    'foo', 'bar', 'baz'
);

This:

echo '<pre>';
print_r(array_keys($input));
echo '</pre>';

Correctly outputs this:

Array
(
    [0] => who
    [1] => what
    [2] => more
    [3] => when
    [4] => 0
    [5] => 1
    [6] => 2
)

It's a trivial solution but somewhat obscure to get there.

I appreciate all the help from everyone. =)

$i = 0;
foreach ($input as $key => $value)
{
    if ($key == 'more')
    {
        // Remove the index "more" from $input and add it to $result.
        $result[] = key(array_splice($input, $i , 1));

    }
    $i++;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top