Loop Array in PHP - php

how to loop an array if the data is 1 or more than 1?
I tried it with
foreach($array['bGeneral'] as $item) {
echo $item['bItem'];
}
but for arrays that have 1 data an error

Basically you need to check if the first element of $array['bGeneral'] is an array or a data value, and if so, process the data differently. You could try something like this:
if (isset($array['bGeneral']['bItem'])) {
// only one set of values
$item = $array['bGeneral'];
// process item
}
else {
// array of items
foreach ($array['bGeneral'] as $item) {
// process item
}
}
To avoid duplication of code, you will probably want to put the item processing code in a function.
Alternatively you could create a multi-dimensional array when you only have one value and then continue processing as you do with multiple values:
if (isset($array['bGeneral']['bItem'])) {
$array['bGeneral'] = array($array['bGeneral']);
}
foreach ($array['bGeneral'] as $item) {
// process item
}

Don't forget recursion - sometimes it is a best choise :
function scan_data($data, $path = null) {
if (!is_array($data))
echo "{$path} : {$data}\n";
else
foreach ($data as $k => $v)
scan_data($v, $path . '/' . $k);
}
$data = [
['a' => 1, 'b' => 2],
['a' => ['c' => 3, 'd' => 4], 'b' => 5],
['a' => 1, 'b' => ['e' => ['f' => 1, 'g' => 2], 'h' => 6] ]
];
scan_data($data);
Output:
/0/a : 1
/0/b : 2
/1/a/c : 3
/1/a/d : 4
/1/b : 5
/2/a : 1
/2/b/e/f : 1
/2/b/e/g : 2
/2/b/h : 6

Related

php Optimize multiarray search

I am reading in a file with thousands of lines. I grab the id from each line and check to see if it is in a multiarray, that also has thousands of entries. If it is in the multiarray I need to have the key of the array it is in. I have this all working with the code shown below but it takes a very long time. I'm hoping someone can suggest a way to do it faster?
$array = [['id' => 'A202977', '550' => 0, '710' => 0],
['id' => 'A202978', '550' => 0, '710' => 0],
['id' => 'A202979', '550' => 0, '710' => 0]
];
$found = InMultiArray('A202978', $array);
$key = MultiArraySearch('A202978', $array);
echo 'Found '.$found .' at '.$key.'<br>';
//shows Found 1 at 1
function InMultiArray($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && InMultiArray($needle, $item, $strict))) {
return true;
}
}
return false;
}
function MultiArraySearch($needle, $haystack) {
foreach ($haystack as $key => $item) {
if (($needle == $item['id'])) {
return $key;
}
}
return FALSE;
}
You can safely and soundly cache the resulting resources into a JSON file, so next time when you need to load the data, you can just grab the content of the JSON file and pass it as a parameter to json_decode.
So, this is how you could proceed:
if the cached file does not exist or it is old, or it is older than the input file
proceed in the old and slow way
pass the result to json_encode and save it into a cache file
else
load the cache file's content
pass it as a parameter to json_decode and you have your result
Alternatively, you can use a database or even a cache-system, like Redis.
If you really need to find the index of the row by the ID field, you can create an associative array of IDs to array indices.
$array = [['id' => 'A202977', '550' => 0, '710' => 0],
['id' => 'A202978', '550' => 0, '710' => 0],
['id' => 'A202979', '550' => 0, '710' => 0]
];
// Array to map ID to array index in $dataRaw
$idIndexMap = [];
// Populate structs
foreach ($array as $i=>$currRow)
{
$idIndexMap[$currRow['id']] = $i;
}
$found = array_key_exists('A202978', $idIndexMap);
$key = $idIndexMap['A202978'];
echo 'Found ' . $found . ' at ' . $key . '<br>';
//shows Found 1 at 1
However if you just need to find the actual row by the ID, it's probably easier to just create an associative array that maps the ID to the actual row.
<?php
$array = [['id' => 'A202977', '550' => 0, '710' => 0],
['id' => 'A202978', '550' => 0, '710' => 0],
['id' => 'A202979', '550' => 0, '710' => 0]
];
// Array to map ID to array index in $dataRaw
$map = [];
// Populate structs
foreach ($array as $currRow)
{
$map[$currRow['id']] = $currRow;
}
$found = array_key_exists('A202978', $map);
$row = $map['A202978'];
echo 'Found ' . json_encode($row) . '<br>';

Two Array Queue Algorithm in php

I have two array, and want to have queueing system in third array in php
Array 1
3
4
5
6
7
Array 2
24 => U //Unavailable
39 => A //Available
55 => A //Available
77 => A //Available
Result expected:-
So in Array 3 I want the one's that are Available
Array 3
39 => 3
55 => 4
77 => 5
Also the data from Array 1 should get deleted once it is assigned to Array 3.
Array 1 should become
6
7
Let me know. Thanks in advance.
I would start with the numbers from $array2 which are available.
$availables = [];
foreach ($array2 as $key => $value) {
if ($value == 'A') $availables[] = $key;
}
Now we have two arrays: $availables and $array1 one, and we need to combine them where one represents the keys and the other the values of the new array. You would do this with this function:
http://nl1.php.net/manual/en/function.array-combine.php
The only thing we need to be careful about is the size of the arrays, so:
$size1 = count($array1);
$size2 = count($availables);
if ($size1 > $size2) $array1 = array_slice($array1,0,$size2);
if ($size2 > $size1) $availables = array_slice($availables,0,$size1);
and then we can combine them:
$array3 = array_combine($availables,$array1);
See: https://eval.in/1056040
It would be better to put this in a function or a method, so that changes in the arrays don't affect the original arrays.
There are, of course, lot's of other ways to do the last two steps, for instance:
$array3 = [];
foreach ($array1 as $key => $number)
{
if (!isset($availables[$key])) break;
$array3[$availables[$key]] = $number;
}
See: https://eval.in/1056044
foreach($array[1] as $key => $value){
if($value === 'A') $array[2][$key] = $value;
}
I would do something like this:
<?php
$quee = range(1, 100);
$stations = ['1' => ['status' => 'A', 'client' => ''], '2' => ['status' => 'A', 'client' => ''], '3' => ['status' => 'U', 'client' => null], '4' => ['status' => 'A', 'client' => '']];
while ($quee) {
foreach ($stations as $name => &$station) {
if ($station['status'] === 'U') {
echo 'Station ' . $name . ' is busy' . PHP_EOL;
$station['status'] = 'A';
} else {
$station['status'] = 'U';
$client = array_shift($quee);
if ($client != null) {
$station['client'] = $client;
echo 'Im doing client ' . $client . ' on station ' . $name . PHP_EOL;
} else {
break;
}
}
}
}

Recursively check value empty or not

I have to check if items with keys 2, 3, 4, 5 in the sub array with index 0 are empty or not. If empty, I need to throw an exception.
If not empty, then move to next iteration, checking items with keys 3, 4, 5, 6 in the sub array with index 1, and so on.
Items with keys 0 and 1 will always be empty so nothings need to be done with them.
So, check for items with key > 1 then 4-4 pair check if anyone is empty and then throw an exception.
here is my code
$array = array(
array('0' => '','1' => '','2' => 'Wasatch standard','3' => 'Wasatch standard','4' => '3,5,2','5' => 'English','6' => '','7' => '','8' => ''),
array('0' => '','1' => '','2' => '','3' => 'ThisIsAtest','4' => 'Wasatch standard1','5' => '3,4,5','6' => 'English','7' => '','8' => ''),
array('0' => '','1' => '','2' => '','3' => '','4' => 'Wasatch standard1.1','5' => 'Wasatch standard1.1','6' => '2','7' => 'Mathematics','8' =>''),
);
for($i=0;$i<count($array);$i++){
checkRecursivelyIfEmpty($array[$i],array('2'+$i,'3'+$i,'4'+$i,'5'+$i));
}
function checkRecursivelyIfEmpty($value,$sumValue){
foreach ($sumValue as $k => $v) {
if(empty($value[$v])){
throw new Exception("Error Processing Request");
}
}
}
The following function first checks whether the input is an array indeed, then checks for the indexes to be empty. If not, then it throws an exception. Furthermore, it traverses the array to see if there are inner arrays. If so, then it recursively checks them as well. After the function there is a quick demonstration of usage.
function checkThings($inputArray, $subArray) {
//If it is not an array, it does not have the given indexes
if (!is_array($inputArray)) {
return;
}
//throws exception if one of the elements in question is not empty
foreach ($subArray as $key) {
if ((isset($inputArray[$key])) && (!empty($inputArray[$key]))) {
throw new Exception("My Exception text");
}
}
//checks for inner occurrences
foreach ($inputArray as $key => $value) {
if (is_array($inputArray[$key])) {
checkThings($inputArray[$key], $subArray);
}
}
}
//Calls checkThings for all elements
for ($index = 0; $index < count($myArray); $index++) {
checkThings($myArray[$index], array($index + 2, $index + 3, $index + 4, $index + 5));
}
Use foreach and check using empty($value)
foreach ($array as $key => $value) {
$value = trim($value);
if (empty($value))
echo "$key empty <br/>";
else
echo "$key not empty <br/>";
}
Assuming the array is named $a you can use this code. The outer loops iterates over all the arrays. The inner loop iterates from $i+2 to $i+5 (in the case of $i=0, you get 2, 3, 4 and 5) on the sub arrays. The function empty() checks that the item is set and not equal to false (for instance, an empty string).
for($i=0; $i<count($a); $++)
for($j=$i+2; $j<$i+6; $j++)
if(empty($a[$i][$j]))
//Raise an error!

Static Algorithm for giving response after user input

I have 2 arrays: F of length 4 and S of length 25
User can select any no of these elements from the above two arrays For eg selecting any 2 from F and 10 from S.Based on what user selected i have give a response to the user from my another array R of length 100.
I tried making if else but was exhausted after creating
100s of them.
So is there any better approach for this ?
My goal is to give user one of the index from array R.
PS. There is no AI(Artificial Intelligence) involved.
EDIT
Currently what i have done is :
if(in_array(1,$F) && in_array(12,$S)){
return $R[3];
}else if(in_array(1,$F) && in_array(17,$s)){
return $R[91];
}else if(in_array(2,$F) && in_array(1,$F) && in_array(21,$S) && in_array(25,$S)){
return $R[23];
}else if(in_array(3,$F) && in_array(21,$S) && in_array(7,$S)){
return $R[17];
}..........
Something like this? Creating map like #zerkms mentioned.
function getRKey(array $f, array $s)
{
// values map by order
$map_r_array = [
3 => ['f' => [1], 's' => [12]],
91 => ['f' => [1], 's' => [17]],
23 => ['f' => [1, 2], 's' => [21, 25]],
17 => ['f' => [3], 's' => [7, 21]],
];
foreach ($map_r_array as $key => $check)
{
// check one by one.
if (!array_diff($check['f'], $f) && !array_diff($check['s'], $s))
{
return $key;
}
}
return null;
}
$f = [1, 2, 3];
$s = [7, 21];
var_dump(getRKey($f, $s)); // int(17)

How to compare 2 array with same key but different value PHP

I want to ask about compare 2 arrays with same key but different value.
I have 1 array master (arrayMaster) and 2 or more array data (arrayData1, arrayData2, and maybe could be more). These array data key will have exactly one of arrayMaster data key (I've done for this thing). For data example that I get:
arrayMaster = Array( [apple] => 1 [banana] => 2 [choco] => 1 [donut] => 2 [egg] => 1 )
arrayData1 = Array( [apple] => 8 [banana] => 2 [choco] => 1 )
arrayData2 = Array( [donut] => 5 [choco] => 2 [egg] => 3 )
(We can see that arrayData1 and arrayData2 contain a key from arrayMaster key.)
These arrays I want to compare and give a calculating method. If the array key at arrayData(n) found at arrayMaster, it will do a calculating data, let said it will sum each other.
So, the result is:
arrayResult1 = 1+8 (apple have 1 from master, apple have 8 from arrayData1), 2+2, 1+1
arrayResult2 = 2+5 (donut have 2 from master, donut have 5 from arrayData2), 1+2, 1+3
So I will have 2 new array (or more, depend on how much arrayData) that contain:
arrayResult1 = ([apple] => 9 [banana] => 4 [choco] => 2);
arrayResult2 = ([donut] => 7 [choco] => 3, [egg] => 4);
Anyone know how to do this? I’”ve tried array_intersect but it didn’t work.
Do something like this:
function doCalc($master, $slave) {
$results = array();
foreach( $slave as $key => $value ) {
if( !isset($master[$key]) ) {
$results[$key] = $value;
}
else {
$results[$key] = $master[$key] + $value;
}
}
return $results;
}
$arrayResult1 = doCalc($arrayMaster, $arrayData1);
$arrayResult2 = doCalc($arrayMaster, $arrayData2);
You can write something simpler like this..
function modifyArr(&$arr,$basearray) //<=-- See I am passing & (reference) so your original array will be modified
{
foreach($arr as $k=>$v)
{
if(array_search($k,$basearray)!==null)
{
$arr[$k]=$basearray[$k]+$arr[$k];
}
}
}
modifyArr($arrayData1,$arrayMaster); //<=-- Pass your 1st array
modifyArr($arrayData2,$arrayMaster); //<=-- Pass your 2nd array
Demonstration
Using these as examples:
arrayResult1 = 1+8 (apple have 1 from master, apple have 8 from arrayData1), 2+2, 1+1
arrayResult2 = 2+5 (donut have 2 from master, donut have 5 from arrayData2), 1+2, 1+3
Why not just do this:
// The main arrays for master & data values.
$arrayMaster = array('apple' => 1, 'banana' => 2, 'choco' => 1, 'donut' => 2, 'egg' => 1);
$arrayData1 = array('apple' => 8, 'banana' => 2, 'choco' => 1);
$arrayData2 = array('donut' => 5, 'choco' => 2, 'egg' => 3);
// Set a values to check array.
$values_to_check = array('apple', 'donut');
// Init the results array.
$results_array = array();
// Roll through the values to check.
foreach ($values_to_check as $value) {
// Check if the array key exists in '$arrayMaster'.
if (array_key_exists($value, $arrayMaster)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayMaster[$value];
// Check if the array key exists in '$arrayData1'.
if (array_key_exists($value, $arrayData1)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayData1[$value];
}
// Check if the array key exists in '$arrayData2'.
if (array_key_exists($value, $arrayData2)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayData2[$value];
}
}
}
// Roll through the results array and use 'array_sum' to get a sum of values.
foreach ($results_array as $results_key => $results_value) {
echo $results_key . ' : ' . array_sum($results_value) . '<br />';
}
But looking at your example, I am unclear on why you have separate arrays for $arrayData1 and $arrayData2 so here is the same code, but refactored to have nested arrays in $arrayData which should be more efficient:
// The main arrays for master & data values.
$arrayMaster = array('apple' => 1, 'banana' => 2, 'choco' => 1, 'donut' => 2, 'egg' => 1);
$arrayData = array();
$arrayData[] = array('apple' => 8, 'banana' => 2, 'choco' => 1);
$arrayData[] = array('donut' => 5, 'choco' => 2, 'egg' => 3);
// Set a values to check array.
$values_to_check = array('apple', 'donut');
// Init the results array.
$results_array = array();
// Roll through the values to check.
foreach ($values_to_check as $value) {
// Check if the array key exists in '$arrayMaster'.
if (array_key_exists($value, $arrayMaster)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayMaster[$value];
// Roll through the values to check.
foreach ($arrayData as $arrayData_value) {
// Check if the array key exists in '$arrayData1'.
if (array_key_exists($value, $arrayData_value)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayData_value[$value];
}
}
}
}
// Roll through the results array and use 'array_sum' to get a sum of values.
foreach ($results_array as $results_key => $results_value) {
echo $results_key . ' : ' . array_sum($results_value) . '<br />';
}

Categories