PHP Array Inconsistency? - php

I have some code that pushes values into a PHP array via array_push(). However, when I do print_r() on the array, it skips a key, and the ending result looks like this:
Array (
[0] => appease
[1] => cunning
[2] => derisive
[3] => effeminate
[4] => grievance
[5] => inadvertently miscreants
[7] => ominous
[8] => resilient
[9] => resolute
[10] => restrain
[11] => superfluous
[12] => trudged
[13] => undiminished
)
As you can see, it skipped the 6th value, and moved onto the next one. For some reason though, if I call the foreach() method on the array, it stops after "grievance", or index 4. Does anyone know why it does this?
Edit: if I do echo $words[6], it prints the value of the 6th index correctly.
Edit 2: here's my code:
$return = file_get_contents($target_file);
$arr = explode('<U><B>', $return);
$a = 1;
$words = [];
foreach($arr as $pos) {
$important = substr($arr[$a], 0, 20);
$arr2 = explode("</B></U>",$important);
array_push($words,strtolower(trim($arr2[0])));
$a++;
}
Contents of the file are:
<U><B>appease</B></U><U><B>cunning</B></U><U><B>derisive</B></U><U><B>effeminate</B></U><U><B>grievance</B></U><U><B>inadvertently</B></U><U><B>miscreants</B></U><U><B>ominous</B></U><U><B>resilient</B></U><U><B>resolute</B></U><U><B>restrain</B></U><U><B>superfluous</B></U><U><B>trudged</B></U><U><B>undiminished</B></U>
*removed some irrelevant file content for easier readability

i wrote something simplier:
<?php
$return="<U><B>appease</B></U><U><B>cunning</B></U><U><B>derisive</B></U><U><B>effeminate</B></U><U><B>grievance</B></U><U><B>inadvertently</B></U><U><B>miscreants</B></U><U><B>ominous</B></U><U><B>resilient</B></U><U><B>resolute</B></U><U><B>restrain</B></U><U><B>superfluous</B></U><U><B>trudged</B></U><U><B>undiminished</B></U>";
$arr = explode('<U><B>', $return);
$words = [];
foreach($arr as $pos) {
if(!empty($pos)){
$words[]=strip_tags($pos);
}
}
echo '<pre>';
print_r($words);
demo: http://codepad.viper-7.com/XeUWui

$arr = "<U><B>appease</B></U><U><B>cunning</B></U><U><B>derisive</B></U><U><B>effeminate</B></U><U><B>grievance</B></U><U><B>inadvertently</B></U><U><B>miscreants</B></U><U><B>ominous</B></U><U><B>resilient</B></U><U><B>resolute</B></U><U><B>restrain</B></U><U><B>superfluous</B></U><U><B>trudged</B></U><U><B>undiminished</B></U>";
$arr = explode('<U><B>', $arr);
$a = 1;
foreach($arr as &$pos)
{
if(!empty($pos))
{
$pos = str_replace("</B></U>","",$pos);
}
}
print_r(array_filter($arr));

Might be overkill but there is always SimpleXml as well:
$arr = "<U><B>appease</B></U><U><B>cunning</B></U><U><B>derisive</B></U><U><B>effeminate</B></U><U><B>grievance</B></U><U><B>inadvertently</B></U><U><B>miscreants</B></U><U><B>ominous</B></U><U><B>resilient</B></U><U><B>resolute</B></U><U><B>restrain</B></U><U><B>superfluous</B></U><U><B>trudged</B></U><U><B>undiminished</B></U>";
$xml = new SimpleXmlElement('<root>' . $arr . '</root>');
$words = $xml->xpath('//B');
foreach ($words as $i =>$word) {
printf("%d.\t%s\n", $i+1, $word);
}

This is pretty simple with regex:
<?php
$words = "<U><B>appease</B></U><U><B>cunning</B></U><U><B>derisive</B></U><U><B>effeminate</B></U><U><B>grievance</B></U><U><B>inadvertently</B></U><U><B>miscreants</B></U><U><B>ominous</B></U><U><B>resilient</B></U><U><B>resolute</B></U><U><B>restrain</B></U><U><B>superfluous</B></U><U><B>trudged</B></U><U><B>undiminished</B></U>";
preg_match_all("#<U><B>(.*?)</B></U>#",$words,$matches);
print_r($matches[1]);
?>
Fiddle here

Related

How do I put a specific string from an array that came from a file in PHP?

Hi I have been doing this project for almost a month now. Is there's anyway I can store the value of the next string after the searched string in the list of array?
For example:
Deviceid.txt content is:
Created:21/07/2016 1:50:53; Lat:30.037853; Lng:31.113798; Altitude:79; Speed:0; Course:338; Type:Gps;
Created:21/07/2016 1:49:53; Lat:30.037863; Lng:31.113733; Altitude:60; Speed:0; Course:338; Type:Gps;
Here is my sample php coding
$file_handle = fopen("data/deviceid.txt", "r");
while (!feof($file_handle)) {
$line = fgets($file_handle);
array_push($a,$line);
}
$searchword = 'Lat';
$matches = array_filter($a, function($var) use ($searchword) {
return preg_match("/\b$searchword\b/i", $var);
});
print_r($matches);
fclose($file_handle);
Matches Data:
[0] = 30.037853
[1] = 30.037863
After parsing the file with the code below, you can use array_column (php v5.5.0+) to get all values from a specific key, like so:
array_column($parsed, 'Lat');
Output:
Array
(
[0] => 30.037853
[1] => 30.037863
)
See it in action here.
And here is the code to parse the content of the file:
// $a = each line of the file, just like you're doing
$a = array_filter($a); // remove empty lines
$parsed = array();
foreach($a as $v1){
$a1 = explode(';', $v1);
$tmp = array();
foreach($a1 as $v2){
$t2 = explode(':', $v2);
if(count($t2) > 1){
$tmp[trim(array_shift($t2))] = trim( implode(':', $t2) );
}
}
$parsed[] = $tmp;
}
This is the structure of $parsed:
Array
(
[0] => Array
(
[Created] => 21/07/2016 1:50:53
[Lat] => 30.037853
[Lng] => 31.113798
[Altitude] => 79
[Speed] => 0
[Course] => 338
[Type] => Gps
)
[1] => Array
(
[Created] => 21/07/2016 1:49:53
[Lat] => 30.037863
[Lng] => 31.113733
[Altitude] => 60
[Speed] => 0
[Course] => 338
[Type] => Gps
)
)
See the code in action here.
I wrote a quick regex that can help you pull the field names and values from each line.
You may try with this:
$re = "/((?P<fieldname>[^\\:]*)\\:(?P<fieldvalue>[^\\;]*); *)/";
$str = "Created:21/07/2016 1:50:53; Lat:30.037853; Lng:31.113798; Altitude:79; Speed:0; Course:338; Type:Gps;";
preg_match_all($re, $str, $matches);
Do a print_r of $matches to inspect the results.
Hope this helps.
After your array_filter, iterate through your matches and apply a more specific regex to each line:
$lats = array();
foreach ($matches as $line)
{
$match = array();
preg_match("/\b$searchword:([\d\.]+);/i", $var, $match);
$lats[] = $match[1];
}
print_r($lats);
The variable $match will be populated with the full regex match at index 0, and the parenthesized match at index 1.

Multi-array with one output

Here is my code, which currently does not working properly. How can I make it working? My wish is to make output like one string (of course I know how to "convert" array to string):
words altered, added, and removed to make it
Code:
<?php
header('Content-Type: text/html; charset=utf-8');
$text = explode(" ", strip_tags("words altered added and removed to make it"));
$stack = array();
$words = array("altered", "added", "something");
foreach($words as $keywords){
$check = array_search($keywords, $text);
if($check>(-1)){
$replace = " ".$text[$check].",";
$result = str_replace($text[$check], $replace, $text);
array_push($stack, $result);
}
}
print_r($stack);
?>
Output:
Array
(
[0] => Array
(
[0] => words
[1] => altered,
[2] => added
[3] => and
[4] => removed
[5] => to
[6] => make
[7] => it
)
[1] => Array
(
[0] => words
[1] => altered
[2] => added,
[3] => and
[4] => removed
[5] => to
[6] => make
[7] => it
)
)
Without more explanation it's as simple as this:
$text = strip_tags("words altered added and removed to make it");
$words = array("altered", "added", "something");
$result = $text;
foreach($words as $word) {
$result = str_replace($word, "$word,", $result);
}
Don't explode your source string
Loop the words and replace the word with the word and added comma
Or abandoning the loop approach:
$text = strip_tags("words altered added and removed to make it");
$words = array("altered", "added", "something");
$result = preg_replace('/('.implode('|', $words).')/', '$1,', $text);
Create a pattern by imploding the words on the alternation (OR) operator |
Replace found word with the word $1 and a comma
You can use an iterator
// Array with your stuff.
$array = [];
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($iterator as $value) {
echo $v, " ";
}
Your original approach should work with a few modifications. Loop over the words in the exploded string instead. For each one, if it is in the array of words to modify, add the comma. If not, don't. Then the modified (or not) word goes on the stack.
$text = explode(" ", strip_tags("words altered added and removed to make it"));
$words = array("altered", "added", "something");
foreach ($text as $word) {
$stack[] = in_array($word, $words) ? "$word," : $word;
}

Putting an array (at the end OR beginning) subarray of another array

Say I got this array:
array([0] => 0 [1] => 0 [2] => 1), how can I put this as the value of the nth key of another array, making
$array = array(
[0] => array([0] => 0 [1] => 0 [2] => 1)
)
in this example it is the 0th key of array $array
I had browsed with PHP array functions, but I got tired looking for a function that does the same thing
EDIT.
Doing: $array[0] = array(0, 0, 1); works great for first loop, but if I would like to add another array as subarray, say array(1, 1, 1), my output should be
$array = array(
[0] => array([0] => 0 [1] => 0 [2] => 1 [3] => 1 [4] => 1 [5] => 1)
)
Note that the new array, was added at the end of the last subarray.
Please help! thanks!
EDIT
$x=0;
while($x<count($WOE_CONTROL)) {
$j=0;
while($j<=30) {
if ($WOE_CONTROL[$x+3]&(1<<$j)) {
echo '<br />';
echo '<strong>'.$Castles[$j].'</strong>';
$castle_data_holder[0] = $WOE_CONTROL[$x];
$castle_data_holder[1] = $WOE_CONTROL[$x+1];
$castle_data_holder[2] = $WOE_CONTROL[$x+2];
$castle_db[$j] = $castle_data_holder;
unset ($castle_data_holder);
}
if ($x+4 < count($WOE_CONTROL)) {echo " ";}
$j=$j+1;
}
$x=$x+4;
}
Sorry, there, I am trying to extract all the data in $WOE_CONTROL which actually contains binary data, then store them temporarily to $castle_data_holder then finally, add it to $castle_db
Just set the value of $array[0] to the array. This produces a multidimensional array.
$array[0] = array(0, 0, 1);
Is this u looking for?
$array[] = array(0,0,1);
$array[] = array(1,1,1);
$array[] = array(2,2,2);
// etc...
print_r($array);
EDIT
$array[]['a1'] = array(1,1,1);
$array[]['a2'] = array(2,2,2);
$array[]['a3'] = array(3,3,3);
// etc...
print_r($array);
Finally this is u need
$a = array(1,1,1);
$b = array(2,2,2);
$c = array(3,3,3);
$value = array_merge($a,$b,$c);
print_r($value);
EDIT
$newArray = array();
foreach($yourArray as $key => $value)
{
// I say if $value is an array that u want to merge
$arrayToMerge = $value;
$newArray = array_merge($newArray,$arrayToMerge);
}
print_r($newArray);
This solved my problem:
if (empty($castle_db[$j])) {
$castle_db[$j] = $castle_data_holder;
}
else {
$castle_db[$j] = array_merge($castle_db[$j],$castle_data_holder);
}
it is going to check if the array is empty if not use merge.
Thanks everyone!

Create an array within an array using a string from key

I can't get past making what I think is a 2D Array in PHP. I'm using a CSV as source input and want to take one of the columns and split that into an array as well.
$csv = array_map("str_getcsv", file("data/data.csv", FILE_SKIP_EMPTY_LINES));
$keys = array_shift($csv);
foreach ($csv as $i => $row) {
$csv[$i] = array_combine($keys, $row);
$linkto = $csv[$i]['linkto'];
// $linktoArray = explode(" ", $linkto);
echo '<pre>';
// print_r($linktoArray);
echo '</pre>';
$csv[$i] = array_combine($keys, $row);
}
$csv['timestamp'] = time();
echo '<pre>';
print_r($csv);
echo '</pre>';
Will output:
Array
(
[0] => Array
(
[color] => 1
[shape] => 0
[label] => string
[size] => 1
[linkto] => 1 2 3
)...
Using something similar to what I commented out, I'd love to see something like:
Array
(
[0] => Array
(
[color] => 1
[shape] => 0
[label] => string
[size] => 1
[linkto] => Array
(
[0]=>1
[1]=>2
[2]=>3
)
)...
However, right now I'm just getting an array before my containing array. Pardon my ignorance, I haven't had much experience past the front-end. Any suggestions? I'm sure this has been explained before, but I can't find the right terminology to utilize a search.
It's fairly straight forward. All you need to do is this:
$linkto = $csv[$i]['linkto'];
$linktoArray = explode(" ", $linkto);
$csv[$i]['linkto'] = $linktoArray;
After having read through your code again, you seem to be struggling with the concept of foreach. When you use foreach you don't access $csv[$i] like you have, you just use $row. Try something like:
//The & symbol means any changes made to $row inside the foreach will apply outside the foreach.
foreach($csv as $i => &$row) {
$row['linkto'] = explode(" ", $row['linkto']);
}
That should be all you need, none of this array_combine stuff.
Here is a modified example from the SplFileObject::fgetcsv documentation that might simplify your code enough to isolate what might be giving you issues:
$file = new SplFileObject("data/data.csv");
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY);
$header_row = ($file->fgetcsv());
foreach ($file as $row) {
$row = array_combine($header_row, $row);
$row['linkto'] = explode(" ", $row['linkto']);
$csv[] = $row;
}
print_r($csv);

Big string to nice array

I need to make big string into a nice array. String itself is list of tags and tag ids. There can be any amount of them. Here is example of the string: 29:funny,30:humor,2:lol - id:tag_name. Now, I have problem converting it to array - Array ( [29] => funny [30] => humor ). I can get to the part where tags are as so
Array (
[0] = Array (
[0] = 29
[1] = funny
)
[1] = Array (
[0] = 30
[1] = humor
)
)
I've look at array functions too but seems none of them could help me.
Can anyone help me out?
Here's some code to get you going:
$str = "29:funny,30:humor,2:lol";
$arr = array();
foreach (explode(',', $str) as $v) {
list($key, $val) = explode(':', $v);
$arr[$key] = $val;
}
print_r($arr);
/* will output:
Array
(
[29] => funny
[30] => humor
[2] => lol
)
*/
You could replace the foreach with an array_map for example, but I think it's simpler for you this way.
Here's an example of it working: http://codepad.org/4BpnCiEJ
You could use explode() to do this, though it would take two passes. The first to split the string into pairings (explode (',', $string)) and the second to split each paring
$arr = explode (',', $string);
foreach ($arr as &$pairing)
{
$pairing = explode (':', $pairing);
}
$string = '29:funny,30:humor,2:lol';
$arr1 = explode(',', $string);
$result = array();
foreach ($arr1 as $element1) {
$result[] = explode(':', $element1);
}
print_r($result);
You can use preg_match_all
preg_match_all('#([\d]+):([a-zA-Z0-9]+)#', $sString, $aMatches);
// Combine the keys with the values.
$aArray = array_combine($aMatches[1], $aMatches[2]);
echo "<pre>";
print_r($aArray);
echo "</pre>";
Outputs:
Array
(
[29] => funny
[30] => humor
[2] => lol
)
<?php
$test = '29:funny,30:humor,2:lol';
$tmp_array = explode(',', $test);
$tag_array = ARRAY();
foreach ($tmp_array AS $value) {
$pair = explode(':', $value);
$tag_array[$pair[0]] = $pair[1];
}
var_dump($tag_array);
?>

Categories