Reputation: 4862
Can someone please put me out of my misery and explain why I'm missing the middle value when I try to push the results of a preg_match into another array? It's either something silly or a vast gap in my understanding. Either way I need help. Here is my code:
<?php
$text = 'The group, which gathered at the Somerfield depot in Bridgwater, Somerset,
on Thursday night, complain that consumers believe foreign meat which has been
processed in the UK is British because of inadequate labelling.';
$word = 'the';
preg_match_all("/\b" . $word . "\b/i", $text, $matches, PREG_OFFSET_CAPTURE);
$word_pos = array();
for($i = 0; $i < sizeof($matches[0]); $i++){
$word_pos[$matches[0][$i][0]] = $matches[0][$i][1];
}
echo "<pre>";
print_r($matches);
echo "</pre>";
echo "<pre>";
print_r($word_pos);
echo "</pre>";
?>
I get this output:
Array
(
[0] => Array
(
[0] => Array
(
[0] => The
[1] => 0
)
[1] => Array
(
[0] => the
[1] => 29
)
[2] => Array
(
[0] => the
[1] => 177
)
)
)
Array
(
[The] => 0
[the] => 177
)
So the question is: why am I missing the [the] => 29? Is there a better way? Thanks.
Upvotes: 1
Views: 289
Reputation: 20534
What is happening actually :
when i=0,
$word_pos[The] = 0 //mathches[0][0][0]=The
when i=1
$word_pos[the] = 29
when i=3
$word_pos[the] = 177 //here this "the" key overrides the previous one
//so your middle 'the' is going to lost :(
Now an array based solution can be like this :
for($i = 0; $i < sizeof($matches[0]); $i++){
if (array_key_exists ( $matches[0][$i][0] , $word_pos ) ) {
$word_pos[$matches[0][$i][0]] [] = $matches[0][$i][1];
}
else $word_pos[$matches[0][$i][0]] = array ( $matches[0][$i][1] );
}
Now if you dump $word_pos the output should be :
Array
(
[The] => Array
(
[0] => 0
)
[the] => Array
(
[0] => 29 ,
[1] => 177
)
)
Hope that helps.
Reference : array_key_exist
Upvotes: 1
Reputation: 2068
First you assign $word_pos["the"] = 29
and then you OVERWRITE IT with $word_pos["the"] = 177
.
You don't overwrite The
because indexes are case sensitive.
So maybe use an array of objects like this:
$object = new stdClass;
$object->word = "the"; // for example
$object->pos = 29; // example :)
and assign it to an array
$positions = array(); // just init once
$positions[] = $object;
alternatively you can assign an associative array instead of the object, so it would be like
$object = array(
'word' => 'the',
'pos' => 29
);
OR assign the way you do, but instead of overwriting, just add it to an array, like:
$word_pos[$matches[0][$i][0]][] = $matches[0][$i][1];
instead of
$word_pos[$matches[0][$i][0]] = $matches[0][$i][1];
so you get something like:
Array
(
[The] => Array
(
[0] => 0
)
[the] => Array
(
[0] => 29
[1] => 177
)
)
Hope that helps :)
Upvotes: 1
Reputation: 318558
PHP arrays are 1:1 mappings, i.e. one key points to exactly one value. So you are overwriting the middle value since it also has the key the
.
The easiest solution would be using the offset as the key and the matched string as the value. However, depending on what you want to do with the results a completely different structure might be more appropriate.
Upvotes: 1