PHP Multidimensional Array Length - php

This is a multidimensional PHP array.
$stdnt = array(
array("Arafat", 12210261, 2.91),
array("Rafat", 12210262, 2.92),
array("Marlin", 12210263, 2.93),
array("Aziz", 12210264, 2.94),
);
I can find out the length of the array. That means
count($stdnt); // output is 4
[
array("Arafat", 12210261, 2.91),
array("Rafat", 12210262, 2.92),
array("Marlin", 12210263, 2.93),
array("Aziz", 12210264, 2.94)
] `
But can't get the internal array length.
How can I ?

If you are assuming the subarrays are all the same length then:
$count = count($stdnt[0]);
If you don't know the keys:
$count = count(reset($stdnt));
To get an array with a separate count of each of the subarrays:
$counts = array_map('count', $stdnt);

The other way to count internal array lengths is to iterate through the array using foreach loop.
<?php
$stdnt = array(
array("Arafat", 12210261, 2.91),
array("Rafat", 12210262, 2.92),
array("Marlin", 12210263, 2.93),
array("Aziz", 12210264, 2.94),
);
foreach($stdnt as $s)
{
echo "<br>".count($s);
}
?>

please use sizeof function or count function with recursive
e.g echo (sizeof($stdnt,1) - sizeof($stdnt)) ; // this will output you 9 as you want .
first sizeof($stdntt,1) ; // will output you 13 . count of entire array and 1 mean recursive .

According to the hint from Meaning of Three dot (…) in PHP, the following code is what I usually use for this case:
$stdnt = array(
array("Arafat", 12210261, 2.91),
array("Rafat", 12210262, 2.92),
array("Marlin", 12210263, 2.93),
array("Aziz", 12210264, 2.94),
);
echo count(array_merge(...$stdnt));
The Splat operator "..." will only work,
Only if the first level keys are in integer, ie, not "strings"
PHP > 5.6

// You may try as per this sample
$cars=array(
array("volvo",43,56),
array("bmw",54,678)
);
$mySubSize=sizeof($cars);
for ($i=0;$i<$mySubSize;$i++) {
foreach ($cars[$i] as $value) {
echo "$value <br>";
}
}

Related

Replace array value with more than one values

I have an array like this,
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
I want to find any value with an ">" and replace it with a range().
The result I want is,
array(
1,2,3,4,5,6,7,8,9,10,11,12, '13.1', '13.2', 14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
);
My understanding:
if any element of $array has '>' in it,
$separate = explode(">", $that_element);
$range_array = range($separate[0], $separate[1]); //makes an array of 4 to 12.
Now somehow replace '4>12' of with $range_array and get a result like above example.
May be I can find which element has '>' in it using foreach() and rebuild $array again using array_push() and multi level foreach. Looking for a more elegant solution.
You can even do it in a one-liner like this:
$array = array(1,2,3,'4>12','13.1','13.2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,#range(...array_slice(explode(">","$c>$c"),0,2)));},
[]
));
I avoid any if clause by using range() on the array_slice() array I get from exploding "$c>$c" (this will always at least give me a two-element array).
You can find a little demo here: https://rextester.com/DXPTD44420
Edit:
OK, if the array can also contain non-numeric values the strategy needs to be modified: Now I will check for the existence of the separator sign > and will then either merge some cells created by a range() call or simply put the non-numeric element into an array and merge that with the original array:
$array = array(1,2,3,'4>12','13.1','64+2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,strpos($c,'>')>0?range(...explode(">",$c)):[$c]);},
[]
));
See the updated demo here: https://rextester.com/BWBYF59990
It's easy to create an empty array and fill it while loop a source
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$res = [];
foreach($array as $x) {
$separate = explode(">", $x);
if(count($separate) !== 2) {
// No char '<' in the string or more than 1
$res[] = $x;
}
else {
$res = array_merge($res, range($separate[0], $separate[1]));
}
}
print_r($res);
range function will help you with this:
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$newArray = [];
foreach ($array as $item) {
if (strpos($item, '>') !== false) {
$newArray = array_merge($newArray, range(...explode('>', $item)));
} else {
$newArray[] = $item;
}
}
print_r($newArray);

php foreach group results by 3 sets of characters

I am trying to group some foreach results based on the first 3 sets of characters.
For example i am currently listing sku codes for products and they look like this:
REF-MUSBOM-0500-ORA
REF-PROCOF-0001-LAT
REF-WHEREF-0001-TRO
REF-WHEREF-0001-ORA
REF-SHAKER-0700-C/B
REF-CREMON-0100-N/A
REF-GLUSUL-0090-N/A
REF-CRECAP-0090-N/A
REF-ALBFER-0120-N/A
REF-TSHCOT-LARG-BLK
REF-TSHCOT-MEDI-BLK
REF-ALBMAG-0090-N/A
REF-GYMJUG-2200-N/A
REF-OMEGA3-0090-N/A
REF-NEXGEN-0060-N/A
REF-VITAD3-0100-N/A
REF-SSSHAK-0739-N/A
REF-GINKGO-0090-N/A
REF-DIGEZY-0090-N/A
REF-VEST00-MEDI-N/A
REF-VEST00-LARG-N/A
REF-CREMON-0250-N/A
REF-MSM----0250-N/A
REF-GRNTEA-0100-N/A
REF-COLOST-0100-N/A
REF-GLUCHO-0090-N/A
REF-ZINCMA-0100-N/A
REF-BETALA-0250-N/A
REF-DRIBOS-0250-N/A
REF-HMB000-0090-N/A
REF-ALACID-0090-N/A
REF-CLA000-0090-N/A
REF-ACETYL-0090-N/A
REF-NXGPRO-0090-N/A
REF-LGLUTA-0250-N/A
REF-BCAA20-0200-N/A
REF-FLAPJA-0012-ACR
REF-FLAPJA-0012-MAP
REF-LCARNI-0100-N/A
REF-CORDYC-0090-N/A
REF-CREMON-0500-N/A
REF-BCAAEN-0330-APP
REF-PREWKT-0300-FPU
REF-TESFUS-0090-N/A
REF-AMIIFUS-0300-GAP
REF-AMIIFUS-0300-WME
REF-BCAINT-0400-FPU
REF-KRILLO-0090-N/A
REF-AMIIFUS-0300-PLE
REF-AMIIFUS-0300-FPU
REF-BCAINT-0400-WME
REF-ENZQ10-0090-N/A
REF-THERMO-0100-N/A
REF-LGLUTA-0500-N/A
REF-RBAR00-0012-DCB
REF-RBAR00-0012-PBC
REF-RBAR00-0012-WCR
REF-IMHEAV-2200-CHO
REF-PROCOF-0012-N/A
REF-DIEPRO-0900-STR
REF-DIEPRO-0900-BOF
REF-DIEPRO-0900-CHO
REF-INWPRO-0900-VAN
REF-INWPRO-0900-BOF
REF-INWPRO-0900-BCS
REF-INWPRO-0900-CHO
REF-INWPRO-0900-CMI
REF-INWPRO-0900-RAS
REF-INWPRO-0900-STR
REF-INWPRO-0900-CIN
REF-INWPRO-0900-CPB
REF-EGGPRO-0900-CHO
REF-EGGPRO-0900-VAN
REF-MICCAS-0909-CHO
REF-MICCAS-0909-CMI
REF-MICCAS-0909-VAN
REF-MICCAS-0909-STR
REF-BCAA50-0500-N/A
REF-MICWHE-0909-STR
REF-MICWHE-0909-VAN
REF-MICWHE-0909-CHIO
REF-MICWHE-0909-BAN
REF-1STOXT-2030-STR
REF-1STOXT-2030-VAN
REF-1STOXT-2030-CHO
REF-MUSBOM-0600-BCH
REF-MUSBOM-0600-FPU
REF-MUSBCF-0600-BCH
REF-MUSBCF-0600-FPU
REF-VEGANP-2100-STR
REF-VEGANP-2100-CHO
REF-INMPRO-2270-CPB
REF-DIETMR-2400-CPB
REF-INMPRO-2270-SCR
REF-INMPRO-2270-VIC
REF-MATRIX-1800-FRU
REF-INMPRO-2270-BOF
REF-MATRIX-1800-CHO
REF-INMPRO-2270-CHO
REF-ONESTO-2100-CHO
In the above list there are 2 skus which are:
REF-WHEREF-0001-TRO
REF-WHEREF-0001-ORA
The first 3 sets of characters split by - are the same. What would be the best approach of grouping all results leaving me an array something like this:
Array
(
[REF-WHEREF-0001] => Array
(
[0] => REF-WHEREF-0001-TRO
[1] => REF-WHEREF-0001-ORA
)
)
Are the first 3 groups (excluding the multiple -) always 13 characters? Then do something like this:
<?php
$arr = ["REF-MUSBOM-0500-ORA",
"REF-PROCOF-0001-LAT",
"REF-WHEREF-0001-TRO",
"REF-WHEREF-0001-PPL"];
$resultArr = [];
foreach ($arr as $sku) {
$resultArr[substr($sku, 0, 15)][] = $sku;
}
var_dump($resultArr);
If that length varies you might want to work with a regex or the strpos() of the third -.
I must say that I think you could come up with this yourself, since you were already thinking in the right direction i.e. foreach()
EDIT: Because I found other solutions more elegant looking, I decided to compare efficiency. This solution is a lot faster than the other ones.
I always create a new array with the index that I need for group, try this:
$arr=array('REF-MUSBOM-0500-ORA',
'REF-PROCOF-0001-LAT',
'REF-WHEREF-0001-TRO');
$newarr=array();
foreach($arr as $a){
$b=explode('-',$a);
array_pop($b);
$b=implode("-", $b);
$newarr[$b][]=$a;
}
echo '<pre>',print_r($newarr),'</pre>';
You will need to pick a group with some basics use of explode, implode and str_replace.
What does this solution do.
loop through the array of your items
explode to get last item index of exploded string assuming that it
would be dynamic in the end
implode & str_replace again to find out string of group name
And last strpos & in_array to have sample reponse
Solution
$array = array(
'REF-MUSBOM-0500-ORA',
'REF-PROCOF-0001-LAT',
'REF-WHEREF-0001-TRO',
'REF-WHEREF-0001-ORA',
'REF-SHAKER-0700-C/B',
'REF-CREMON-0100-N/A',
'REF-GLUSUL-0090-N/A',
'REF-CRECAP-0090-N/A',
'REF-ALBFER-0120-N/A',
);
$new_array = array();
foreach ($array as $key => $val) {
$group_arr = explode('-', $val);
$end = end($group_arr);
$combined_group = implode('-', $group_arr);
$group = str_replace('-' . $end, '', $combined_group);
if (strpos($val, $group) !== false && !in_array($group, $new_array)) {
$new_array[$group][] = $val;
}
}
echo '<pre>';print_r($new_array);echo '</pre>';
See demo on Sandbox

How to seprate numeric value from charcter using PHP

I need one help.i need to separate numeric value from character using PHP.I am explaining my code below.
$subcatid=a1,a2,4,5
here i have some value with comma separator i need here separate numeric value(i.e-4,5) first and push them into a array then i have to separate rest numeric value from character(i.e-1 from a1,2 from a2) and push those separated value into another array.Please help me.
Try this
<?php
$subcatid="a1,a2,4,5";
$subcatid_arr = explode(",",$subcatid);
$onlynum_subcatid = array_filter($subcatid_arr, 'is_numeric');
$onlynum = implode(",",$onlynum_subcatid );
echo "Only Number : ".$onlynum;
$notnum_subcatid = array_diff($subcatid_arr,$onlynum_subcatid );
$notnum = implode(",",$notnum_subcatid );
echo "\nNot Number : ".$notnum;
?>
Output is :
Only Number : 4,5
Not Number : a1,a2
check here : https://eval.in/539059
Use this code
$subcatid="a1,a2,4,5";
$strArray = explode(',',$subcatid);
$intArr = array();
foreach($strArray as $key=>$value):
if(preg_match('/^[0-9]*$/',$value)):
$intArr[]=$value;
else:
$str2Arr = str_split($value);
foreach($str2Arr as $keyStr=>$lett):
if(preg_match('/^[0-9]*$/',$lett)):
$intArr[]=$lett;
endif;
endforeach;
endif;
endforeach;
var_dump($intArr);
in this code you can expect your result. Do process with the $number, $char array as required
<?php
$subcatid="a1,a2,4,5";
$subcatid_arr = explode(",",$subcatid);
for($i=0;$i<sizeof($subcatid_arr);$i++){
if(is_numeric($subcatid_arr[$i])){
$number[]=$subcatid_arr[$i];
}
else{
$char[]=$subcatid_arr[$i];
}
}
print_r($number);// 4,5
print_r($char);// a1,a2
?>
If I am understanding correctly, you want to put all of the original numeric values into a single array and then filter just the numeric parts of the leftovers and put them in to a second array.
If this is correct then I believe this should do what you want.
<?php
$subcatid = 'a1,a2,4,5';
$subcat_array = explode(",",$subcatid);
$subNums1 = [];
$subNums2 = [];
foreach($subcat_array as $item) {
if(is_numeric($item)) {
// This pushes all numeric values to the first array
$subNums1[] = $item;
} else {
// This strips out everything except the numbers then pushes to the second array
$subNums2[] = preg_replace("/[^0-9]/","",$item);
}
}
print_r($subNums1);
print_r($subNums2);
?>
This will return:
Array (
[0] => 4
[1] => 5
)
Array (
[0] => 1
[1] => 2
)

multi dimension array split with explode PHP

i have multidimension array
$a = "5,add|4,edit|6,add|6,edit|19,add|19,delete|19,view";
then i explode $a
$array_a = explode("|", $a);
//loop
for($i=0;$i<=count($arr_a)-1;$i++){
arr_b = explode(",", $arr_a[$i]);
foreach($arr_b as $id => $access){
echo $id." have access ".$access;
}
}
//result
0 have access 5
1 have access add
0 have access 4
1 have access edit
0 have access 6
1 have access add
0 have access 6
1 have access edit
0 have access 19
1 have access add
0 have access 19
1 have access delete
0 have access 19
1 have access view
//-end result
the problem is :
how i can make the result like this
5 have access add
4 have access edit
6 have access add,edit
19 have access add,delete,view
I think Regex would be a better solution in this case, in case you haven't considered using it.
Sample (Tested):
$a = "5,add|4,edit|6,add|6,edit|19,add|19,delete|19,view";
$result = array();
// match each pair in the input
if (preg_match_all('/(\\d+)\\,(.*?)(\\||$)/m', $a, $matches)){
foreach( $matches[1] as $match_index => $match ){
$result[$match][] = $matches[2][$match_index];
}
}
// loop through the results and print in desired format
foreach( $result as $entry_index => $entry ){
echo "$entry_index have access " . implode( ',', $entry ) . "\n";
}
output:
5 have access add
4 have access edit
6 have access add,edit
19 have access add,delete,view
Using regex simplifies the code and also makes it somewhat easier to change the format of the input that is supported.
The $result array ended up with a hash map using your numeric ids as the keys and arrays of permissions (add, delete, etc) as the value for each key.
Try this one (tested):
// intial data
$strAccess = "5,add|4,edit|6,add|6,edit|19,add|19,delete|19,view";
// build access array
$arrayAccess = array();
$tmpList = explode('|', $strAccess);
foreach($tmpList as $access)
{
list($idUser, $right) = explode(',', $access);
if (!isset($arrayAccess[$idUser]))
$arrayAccess[$idUser] = array();
$arrayAccess[$idUser][] = $right;
}
// print it out
foreach($arrayAccess as $idUser => $accessList)
echo $idUser." has access ".implode(",", $accessList)."\n";
You can use counter something like
$count5=0;
foreach($arr_b as $id => $access){
if($access=='5'){
$count5++;
}
echo $id." have access ".$count5;
}
$a = "5,add|4,edit|6,add|6,edit|19,add|19,delete|19,view";
$array_a = explode("|". $a);
//loop
$aRights = array();
for($i=0;$i<=count($arr_a)-1;$i++){ $arr_b = explode(",", $arr_a[$i]);
foreach($arr_b as $id => $access){
$aRights[$id][] = $access;
}
}
foreach( $aRights as $id=>$rightsList){
echo $id." have access ";
$i=1;
foreach($rightsList as $r){
echo $r;
if($i != count($rightsList)) echo ",";
$i++;
}
}
What about something like hashmapping:
$tobegenerated = array();
$a = explode(yourdelimiter,yourstring);
foreach ($a as $cur)
{
$b = explode(delimiter,$cur);
$tobegenerated[$cur[0]] = $cur[1];
}
//Print hashmap $tobegenerated
This should work, remember that in php arrays are also hash maps
Edit 1:
Arrays in PHP are hash maps. A hash map can be interpreted as an array where keys can be anything and value can be anything too. In this case, you would like to use a hash map because you need to bind values that are "outside" the range of the array (even if they are ints). So a hash map is exactly what you want, allowing to specify anything as a key.
How a hash map work is something that you can search on google or on wikipedia. How arrays work in php can be found here

PHP: Getting to a key in mulitdimensional array?

I have an array like
$myArray =array
(
"0"=>array("dogs",98),
"1"=>array("cats",56),
"2"=>array("buffaloes",78)
)
How can I get a key by providing a value?
e.g. if i search for "buffaloes" array_search may return "2".
Thanks
$myArray =array
(
"0"=>array("dogs",98),
"1"=>array("cats",56),
"2"=>array("buffaloes",78)
);
function findInArray($term, $array) {
foreach($array as $key => $val) {
if(in_array($term, $val, true)) {
return $key;
}
}
}
echo findInArray('buffaloes', $myArray); // 2
echo findInArray(78, $myArray); // 2
function asearch($key, $myArray) {
for ($i = 0; $i < sizeof($myArray); $i++) {
if ($myArray[$i][0] == $key) {
return $i;
}
}
return -1; # no match
}
Though, you'd probably want to restructure your array to:
$myarray = array(
'dogs' => 98,
'cats' => 56,
'buffaloes' => 78
);
And just do:
$myArray['buffaloes']; # 78
The only way you can do it is to iterate over every item and preform a Linear Search
$i = -1;
foreach ($myArray as $key => $item){
if ( $item[0] == 'buffaloes' ){
$i = $key;
break;
}
}
//$i now holds the key, or -1 if it doesn't exist
As you can see, it is really really inefficient, as if your array has 20,000 items and 'buffaloes' is the last item, you have to make 20,000 comparisons.
In other words, you need to redesign your data structures so that you can look something up using the key, for example a better way may be to rearrange your array so that you have the string you are searching for as the key, for example:
$myArray['buffaloes'] = 76;
Which is much much faster, as it uses a better data structure so that it only has to at most n log n comparisons (where n is the number of items in the array). This is because an array is in fact an ordered map.
Another option, if you know the exact value of the value you are searching for is to use array_search
I never heard of built in function. If you want something more general then above solutions you shold write your own function and use recursion. maybe array_walk_recursive would be helpful
You can loop over each elements of the array, testing if the first element of each entry is equal to "buffaloes".
For instance :
foreach ($myArray as $key => $value) {
if ($value[0] == "buffaloes") {
echo "The key is : $key";
}
}
Will get you :
The key is : 2
Another idea (more funny ?), if you want to whole entry, might be to work with array_filter and a callback function that returns true for the "bufalloes" entry :
function my_func($val) {
return $val[0] == "buffaloes";
}
$element = array_filter($myArray, 'my_func');
var_dump($element);
Will get you :
array
2 =>
array
0 => string 'buffaloes' (length=9)
1 => int 78
And
var_dump(key($element));
Gves you the 2 you wanted.

Categories