I want to make a verification that if one of these strings has a length greater than 40 echo "this array contains a string with a length greater than 40". So in this case the index [11] contains a string length that is greater than 40. How can I do that?
array(5) {
[0]=>
string(19) "PEDRO MOACIR LANDIM"
[1]=>
string(19) "ADIR JOAO GASTALDON"
[2]=>
string(18) "ABEL PEDRO MARQUES"
[10]=>
string(28) "ADRIANO CESAR GARCIA JOAQUIM"
[11]=>
string(44) "AUTO VIAÇÃO CATARINENSE LTDA - FLORIANÓPOLIS"
}
foreach ($array as $key => $value) {
if(mb_strlen($value) > 40){
echo "this array contain a string wich lenght is greater than 40: ".$key;
}
}
Since only one of the strings is needed to be detected if it's greater than 40, it's better to break the loop once a number greater than 40 is encountered. This can reduce the number of iterations executed by your for loop if ever the number isn't located at the last index of your array.
foreach ($array as $arr) {
if(mb_strlen($arr) > 40){
echo "this array contain a string wich length is greater than 40";
break;
}
}
You can do this:
<?php
$myStrings = array(
0 => "PEDRO MOACIR LANDIM",
1 => "ADIR JOAO GASTALDON",
2 => "ABEL PEDRO MARQUES",
10 => "ADRIANO CESAR GARCIA JOAQUIM",
11 => "AUTO VIAÇÃO CATARINENSE LTDA - FLORIANÓPOLIS"
);
foreach($myStrings as $key => $string){
//Get length of string
$len = strlen( $string );
if( $len > 40 ){
echo
'this array contain a string wich length is greater than 40. Array key:
' .$key. ' | array string: ' .$string;
break;
}
}
?>
Related
I have a text file named C.txt. The contens of the text file goes as following:
Name, BPrice, SPrice, Display
Nokia 520, 20000, 21000, 1
Xiaomi123, 15000, 17000, 0
Xiaomi Redmi, 30000, 32000, 1
I have accessed the file using the following code:
<?php
$file = fopen("C.txt", "r");
while(!feof($file)){
$content = fgets($file);
$products[] = $content;
}
var_dump($products);
?>
var_dump($products) gives output:
array(4) { [0]=> string(33) "Name, BPrice, SPrice, Display " [1]=> string(29) "Nokia 520, 20000, 21000, 1 " [2]=> string(29) "Xiaomi123, 15000, 17000, 0 " [3]=> string(30) "Xiaomi Redmi, 30000, 32000, 1 " }
What I wanted to do, is to separate the Name, BPrice, SPrice and Display columns and their values using explode() method. So, I tried the following:
<?php
for($i=1; $i<count($products); $i++){
$contents[] = explode(",", $products[$i]);
}
var_dump($contents);
?>
var_dump($contents) yields:
array(3) { [0]=> array(4) { [0]=> string(9) "Nokia 520" [1]=> string(6) " 20000" [2]=> string(6) " 21000" [3]=> string(5) " 1 " } [1]=> array(4) { [0]=> string(9) "Xiaomi123" [1]=> string(6) " 15000" [2]=> string(6) " 17000" [3]=> string(5) " 0 " } [2]=> array(4) { [0]=> string(12) "Xiaomi Redmi" [1]=> string(6) " 30000" [2]=> string(6) " 32000" [3]=> string(3) " 1 " } }
NOTE: I wanted to access only the values of the columns and not the headers, hence for($i=1; $i<count($products); $i++)
Now here is where I'm facing the problem. How do I access this two dimensional array $contents?
I have tried the foreach loop as following:
foreach ($contents as $key => $value) {
echo $value[$key];
}
But that results in:
Nokia 520 15000 32000
I cannot seem to figure out why it is not printing the rest of the two rows! Any help would be greatly appreciated. Thanks in advance! :)
Your problem is in the echo $value[$key];.
The $key variable in this context holds the key of current $contents array member, while you are using it to access the value of the inside array, the product data.
Since this is a multi-dimensional array, you will need multiple loops to print it all out. So if you'd like to do that, it would work like this:
foreach ($contents as $productValues) {
foreach ($productValues as $productValue) {
echo $productValue;
}
echo PHP_EOL;
}
Try this function for parsing cvs files into an associative array with the column names as array keys:
function csvArray($file) {
$csv = array_map('str_getcsv', file($file));
array_walk($csv, function(&$a) use ($csv) {
$a = array_combine($csv[0], $a);
});
array_shift($csv);
return $csv;
}
Then result of
$phones = csvArray('c.txt');
print_r($phones);
Is:
Array
(
[0] => Array
(
[Name] => Nokia 520
[ BPrice] => 20000
[ SPrice] => 21000
[ Display] => 1
)
[1] => Array
(
[Name] => Xiaomi123
[ BPrice] => 15000
[ SPrice] => 17000
[ Display] => 0
)
[2] => Array
(
[Name] => Xiaomi Redmi
[ BPrice] => 30000
[ SPrice] => 32000
[ Display] => 1
)
)
Your array in more readable terms looks like this
[["Nokia 520", "20000", "21000", "1"],
["Xiaomi123", "15000", "17000", "0"],
["Xiaomi Redmi", "30000", "32000", "1"]]
This means that in your foreach, the value of your first key is
["Nokia 520", "20000", "21000", "1"]
The reason you are only getting those values is that you are doing
echo $value[$key];
So essentially you are returning positions 0 1 and 2 of ["Nokia 520", "20000", "21000", "1"], which are the values Nokia 520, 20000 and 21000
To get the values you actually want, you need to perform two foreach loops
foreach ($arr as $keys) {
foreach($keys as $value) {
echo "{$value} ";
}
echo "\n";
}
I am looking for a way to explicitly change some array keys as they will always be the same and the array length will always be the same and then output a single key based on the lowest value. Here is where I am at:
The array code itself look like this:
$t = array($low_score_1,$low_score_2,$low_score_3,$low_score_4,$low_score_5,$low_score_6,$low_score_7,$low_score_8);
Output example:
array(8) { [0]=> string(2) "11" [1]=> string(2) "15" [2]=> string(2) "13" [3]=> string(2) "12" [4]=> string(2) "18" [5]=> string(2) "16" [6]=> string(2) "16" [7]=> string(2) "14" }
So I want to change all 8 keys to each be a specific string. So I need to change the keys and then only output the key of the lowest value in the array. I can only at the moment output the value of the lowest in the array like so:
echo min($t);
And from the array above you can see that 11 is the lowest so that is the one I want to show BUT by ke and not value...
UPDATE
I have managed to set my keys and output both the keys with their retrospective pairs but I just want to show the lowest value by its key.
$t = array(
'a' => $low_score_1,
'b' => $low_score_2,
'c' => $low_score_3,
'd' => $low_score_4,
'e' => $low_score_5,
'f' => $low_score_6,
'g' => $low_score_7,
'h' => $low_score_8,
);
reset($t);
while (list($key, $val) = each($t)) {
echo "$key => $val\n";
}
The output of this looks like:
a => 11 b => 15 c => 13 d => 12 e => 18 f => 16 g => 16 h => 14
As mentioned it's a simple 'find minimum' problem.
Only that you want to save the key of the minimum value.
$t = array($low_score_1,$low_score_2,$low_score_3,$low_score_4,$low_score_5,$low_score_6,$low_score_7,$low_score_8);
//Setting new keys
$t2 = array();
foreach($t as $key => $val){
$key2 = 'score_' . ($key+1);
$t2[$key2] = $val;
}
//Finding the minimum
$min = $t2['score_1'];
$min_key = 0;
foreach($t2 as $key => $val){
if($val < $min){
$min = $val;
$min_key = $key;
}
}
//output
print_r($t2);
echo $min; // the min value
echo $min_key; // the key of the min value
I have a long string that is constructed like this:
randomstring number randomstring number randomstring number
I need to group these random strings and numbers together so that I get an array like this:
array = [[randomstring, number], [[randomstring, number], [randomstring, number]]
I don't know the amount of spaces between the strings and numbers. Any suggestions?
UPDATE
Since Edwin Moller's answer I'm now left with this array:
Array (46) {
[0] =>
array(2) {
[0]=>
string(20) "string"
[1]=>
string(7) "number"
}
[1]=>
array(2) {
[0]=>
string(5) ""
[1]=>
string(7) ""
}
[2] =>
array(2) {
[0]=>
string(10) ""
[1]=>
string(11) ""
}
[3] =>
array(2) {
[0]=>
string(10) ""
[1]=>
string(11) ""
}
[4] =>
array(2) {
[0]=>
string(10) ""
[1]=>
string(11) ""
}
The array elements that have 2 empty elements themselves need to be removed.
I'll leave it with this solution. It's not elegant at all, but I don't know what these 'empty' strings are. It doesn't respond to whitespace, space, any character test so I used the strlen() function:
$str = preg_replace('!\s+!', ' ', $longstring);
$parts = explode(" ", $str);
$nr = count($parts);
for ($i = 0; $i < $nr; $i = $i + 2) {
if(strlen($parts[$i]) > 20) { // ugly, but it works for now..
$tmp[] = [$parts[$i], $parts[$i + 1]];
}
}
// unsetting these elements because they are longer than 30
unset($tmp[0]);
unset($tmp[1]);
unset($tmp[2]);
$longstring = "randomstring1 1001 randomstring2 205 randomstring3 58";
// First, take care of the multiple spaces.
$str = preg_replace('/\s+/', ' ', $longstring);
// split in parts on space
$parts = explode(" ",$str);
$nr = count($parts);
$tmp = array();
for ($i=0; $i<$nr; $i=$i+2){
$tmp[] = array($parts[$i], $parts[$i+1]);
}
echo "<pre>";
print_r($tmp);
echo "</pre>";
You might want to make sure it is an even number. (check $nr).
Edit: OP says you have some empty elements in the array $parts.
I don't know what causes that, possibly some encoding issues, not sure without having the original material (string).
A wild guess: Try to utf8_decode the original string, then do the preg_replace, and then print_r.
Like this:
$longstring = "randomstring1 1001 randomstring2 205 randomstring3 58";
$longstring = utf8_decode($longstring);
$str = preg_replace('/\s+/', ' ', $longstring);
$parts = explode(" ",$str);
echo "<pre>";
print_r($parts);
echo "</pre>";
explode string and then check it like this
Online Demo
$str="randomstring number randomstring number randomstring number";
$exp=explode(" ",$str);
for($i=0;$i<count($exp);$i++)
{
if(trim($exp[$i])=="")
continue;
$result[]=array(0=>$exp[$i],1=>$exp[$i+1]);
$i++;
}
var_dump($result);
Try the following
//Our string
$string = "randomstring 11 randomstring 22 randomstring 33";
//Split them up if they have MORE THAN ONE space
$firstSplit = preg_split('/\s\s+/', $string);
//Set up a new array to contain them
$newArray = array();
//For each of the ones like "randomstring 11"
foreach($firstSplit as $key => $split){
//Split them if they have ONE OR MORE space
$secondSplit = preg_split('/\s+/', $split);
//Add them to the array
//Note: change this part to structure the array however you'd like
$newArray[$key]["string"] = $secondSplit[0];
$newArray[$key]["integer"] = $secondSplit[1];
}
The comments should explain well enough what is happening here, it will leave you with the following:
array (size=3)
0 =>
array (size=2)
'string' => string 'randomstring' (length=12)
'integer' => string '11' (length=2)
1 =>
array (size=2)
'string' => string 'randomstring' (length=12)
'integer' => string '22' (length=2)
2 =>
array (size=2)
'string' => string 'randomstring' (length=12)
'integer' => string '33' (length=2)
I do not know if it is the shortest way but i would say your issue can be consist of this steps
1- convert the multi spaces to one space
2- explode the big string to one array has all the sub string
3- group the elements by loop over the big array
<?php
$str = 'randomstring1 number1 randomstring2 number2 randomstring3 number3';
//remove the spaces and put all the element in one array
$arr = explode(' ', $str);
$space = array('');
$arr = array_values(array_diff($arr, $space));
//now loop over the array and group elements
$result = $temArr = array();
foreach($arr as $index => $element){
if($index % 2){//second element (number)
$temArr[] = $element;
$result[] = $temArr;
$temArr = array();
}else{//first element (randomstring)
$temArr[] = $element;
}
}
//print the result
var_dump($result);die;
?>
First split by 2 or more spaces, then split those groups by the single space.
Try this:
$input = 'randomstring1 number1 randomstring2 number2 randomstring3 number3';
$groups = preg_split("/[\s]{2,}/", $input );
$result = array_map(function($i){
return explode(' ', $i);
}, $groups);
Which gets me this result:
array(3) {
[0] = array(2) {
[0] = string(13) "randomstring1"
[1] = string(7) "number1"
}
[1] = array(2) {
[0] = string(13) "randomstring2"
[1] = string(7) "number2"
}
[2] = array(2) {
[0] = string(13) "randomstring3"
[1] = string(7) "number3"
}
}
I have a Php array that have values of times as array values and timestamps as key array is like this:
array(
144454884=>"12:00am", 145454884=>"12:30am", 144474884=>"1:00am", 144454864=>"1:30am", 143354884=>"1:00am", 144654884=>"1:30am", 1444567584=>"2:00am "
);
Timestamp values in above example are not real I wrote an example they are useless anyway unless your timezone matches mine.
Problem:
I need to get "1:00am" and "1:30am" twice I can get repeating values 1 time as shown in answer here:
php return only duplicated entries from an array
I need both repeating values two times with both keys and values being repeated because I need to eliminate those timestamps from week time on my system because of daylight saving a time is repeating and I don't want to show 1:00am at all I just want to show this time as unavailable.
I am not 100% sure what you wanted but this is what I think you need.
Assuming your input array is called $a
$b = array_flip(array_flip($a));
$c = array_diff_key($a, $b);
$b will contain an array of unique values.
$c will contain the elements that were removed.
Results of $b and $c are as follows:
array(5) {
[144454884] = string(7) "12:00am"
[145454884] = string(7) "12:30am"
[143354884] = string(6) "1:00am"
[144654884] = string(6) "1:30am"
[1444567584] = string(7) "2:00am "
}
array(2) {
[144474884] = string(6) "1:00am"
[144454864] = string(6) "1:30am"
}
This code works :
<?php
$array_new = [];
$array_tmp = [];
$array = array(1=>'1233',2=>'12334',3 =>'Hello' ,4=>'hello', 5=>'U');
//loop trough all elements in array and for ever element create key
//For "world" key is "world"
//For "World" key is "world"
//For "WORLD" key is "world"
//So all this cases have same key and differenet representation eg. "world" => ["world","World","WORLD"]
foreach($array as $k => $v){
$index = strtolower($v);
$array_tmp[$index][] = $v;
}
//loop trough new array with new keys and if there are more than one element(> 1) for some key, all of his representations put in new array
foreach($array_tmp as $k => $v){
if(count($v) > 1){
foreach($v as $k2 => $v2){
$array_new[] = $v2;
}
}
}
echo '<pre>';
print_r($array_new);
echo '<pre>';
A possible solution keeping the key information (I will assign the intermediate results to their own variables otherwise it can be confusing to read)
$array = array(
143354883 => "1:00am",
144454884 => "12:00am",
145454884 => "12:30am",
144474884 => "1:00am",
144454864 => "1:30am",
143354884 => "1:00am",
144654884 => "1:30am",
1444567584 => "2:00am ",
0 => 4,
1 => 4,
2 => 4,
3 => "Test",
4 => "TEST",
5 => "test "
);
// Used this array_iunique function: http://stackoverflow.com/questions/2276349/case-insensitive-array-unique
function array_iunique($array) {
return array_intersect_key(
$array,
array_unique(array_map("StrToLower",$array))
);
}
$unique = array_iunique($array);
// Then get the difference by key, that will give you all the duplicate values:
$diff_key = array_diff_key($array, $unique);
// Now we have to find the values that are in the $diff_key and the $unique because we also want to have those:
$correspondingValues = array_uintersect($unique, $diff_key, "strcasecmp");
// Then we have to combine the $duplicate values with the $diff_key and preserve the keys:
$result = array_replace($correspondingValues, $diff_key);
var_dump($result);
Will result in:
array(10) {
[143354883]=>
string(6) "1:00am"
[144454864]=>
string(6) "1:30am"
[0]=>
int(4)
[3]=>
string(4) "Test"
[144474884]=>
string(6) "1:00am"
[143354884]=>
string(6) "1:00am"
[144654884]=>
string(6) "1:30am"
[1]=>
int(4)
[2]=>
int(4)
[4]=>
string(4) "TEST"
}
Hope someone can point me in the right direction here...
I've got directory paths and partial file outputs form a unix grep. I have a flat array from these outputs. Now I'd like to do a bit of PHP magic to turn this flat array into a more hierarchical multidimensional array for more refined user output
Current array;
array(7) {
[0]=>
string(160) "/home/user/data/section1/dir1/20120107/filename.txt:random text after the colon"
[1]=>
string(160) "/home/user/data/section1/dir1/20120108/filename.txt: More random text after the colon"
[2]=>
string(160) "/home/user/data/section1/dir2/20120107/filename.txt: More random text after the colon"
[3]=>
string(160) "/home/user/data/section1/dir2/20120108/filename.txt: More random text after the colon"
[4]=>
string(160) "/home/user/data/section1/dir3/20120107/filename.txt: More random text after the colon"
[5]=>
string(160) "/home/user/data/section1/dir3/20120106/filename.txt: More random text after the colon"
[6]=>
string(160) "/home/user/data/section1/dir3/20120108/filename.txt: More random text after the colon"
}
What i would really like
array(1) {
array(3) {
["dir"]=>
string(4) "dir1"
["date"]=>
string(8) "20120107"
["text"]=>
array (2) {
[0]=>
string(160) "random text after the colon"
[1]=>
string(160) "More random text after the colon"
}
}
array(3) {
["dir"]=>
string(4) "dir1"
["date"]=>
string(8) "20120108"
["text"]=>
array (2) {
[0]=>
string(160) "More random text after the colon"
[1]=>
string(160) "More random text after the colon"
}
}
array(3) {
["dir"]=>
string(4) "dir2"
["date"]=>
string(8) "20120107"
["text"]=>
array (2) {
[0]=>
string(160) "More random text after the colon"
[1]=>
string(160) "More random text after the colon"
}
}
}
I have tried a lot of foreach's, SPL iterator methods, but i'm just not coming out trumps. Looking for any guidance.
Thanks all
This code (using a for loop):
<?php
$data[] = "/home/user/data/section1/dir1/20120107/filename.txt:random text after the colon";
$data[] = "/home/user/data/section1/dir1/20120108/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir2/20120107/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir2/20120108/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120107/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120106/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120108/filename.txt: More random text after the colon";
for($i = 0; $i < count($data); $i++) {
$data[$i] = str_replace('/home/user/data/section1/','',$data[$i]);
$tmp = explode('/', $data[$i]);
$newData[$i] = array(
'dir' => $tmp[0],
'date' => $tmp[1]
);
$tmp = explode(':', $tmp[2]);
$newData[$i]['fileName'] = $tmp[0];
$newData[$i]['text'] = $tmp[1];
}
print_r($newData);
?>
Or this code (using a foreach loop):
<?php
$data[] = "/home/user/data/section1/dir1/20120107/filename.txt:random text after the colon";
$data[] = "/home/user/data/section1/dir1/20120108/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir2/20120107/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir2/20120108/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120107/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120106/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120108/filename.txt: More random text after the colon";
foreach($data as $d) {
$tmp = explode('/', str_replace('/home/user/data/section1/','',$d));
$tmp2 = explode(':', $tmp[2]);
$newData[] = array(
'dir' => $tmp[0],
'date' => $tmp[1],
'filename' => $tmp2[0],
'text' => $tmp2[1]
);
}
print_r($newData);
?>
Outputs:
Array
(
[0] => Array
(
[dir] => dir1
[date] => 20120107
[fileName] => filename.txt
[text] => random text after the colon
)
[1] => Array
(
[dir] => dir1
[date] => 20120108
[fileName] => filename.txt
[text] => More random text after the colon
)
============ more data here ============
[6] => Array
(
[dir] => dir3
[date] => 20120108
[fileName] => filename.txt
[text] => More random text after the colon
)
)
Explode each string of path with "/".You will get an array after that.Then push required element in the array.
Make a foreach over the first array and preg_match() the elements for the informations you want to extract from each string.
foreach( $firstArray => $strElement )
{
$newArray[] = array();
if( preg_match( "~(?<=section1/)[.-\w]*~i", $strElement, $astrMatches) >= 1 )
$newArray['dir'] = $astrMatches[0];
...etc...
}
function magic($array_of_strings)
{
define('REGEX','_^/home/user/data/section1/(dir\d+)/(\d+)/filename.txt:(.*)$_');
$ret_array = array();
foreach($array_of_strings as $string) {
if (preg_match(REGEX, $string, $matches)) {
$ret_array []= array(
'dir'=>$matches[1],
'date'=>$matches[2],
'text'=>$matches[3],
);
}
}
return $ret_array;
}
Ok this will do the job, you can change the directory structure as much as you like as long as the the last two directories keep the same order /dir/date.
You can add as many strings as you like to the text section of the array by seperating them with multiple colons after the URL. e.g. /blah/dir/date/filename.txt : string 1 : string 2.
Your original array must be called $array.
Enjoy:
foreach ($array as $string) {
$temp = array();
$temp["strings"] = explode(':', $string); //Convert the string into an array using `:` as a seperator
$temp["path"] = explode('/', $temp["strings"][0]); //Convert the url into an array using `/` as a seperator (each directory is it's own entry)
$path_count = count($temp["path"]); //Count number of directories in the url
$output = array(
"dir" => $temp["path"][$path_count - 3],
"date" => $temp["path"][$path_count - 2],
"text" => array()
);
foreach ($temp["strings"] as $index => $value) { //Loop through and add any additional text to array
if ($index) {
array_push($output["text"], trim($value));
}
}
print_r($output);
}
Thanks all for the input and scripts. I have actually learned quite a bit about massaging data into multidimensional arrays from these scripts. Unfortunately, none of them worked out exactly as i wanted. One thing i've learned researching this issue, is, 'is there another way to present the data?' and in this case i found it. A shell script, to search all files, output the filename, and then the relevant text.
find /home/user/data/section1 -name 'filename.txt' | xargs grep -il texttxet |
while read file
do
echo "$file"
grep -i -A 4 texttxet "$file"
done
File:/home/user/data/section1/dir1/20120107/filename.txt
line1
line2
line3
File:/home/user/data/section1/dir1/20120108/filename.txt
line1
line2
File:/home/user/data/section1/dir2/20120108/filename.txt
line1
line2
I can easily get this info in an array from this point. Thanks all again