I have arrays, I don't know how to fix
I already try array_push, array_combine, array_merge, but still nothing.
$distance = array(3) {
[0]=>
float(2.2)
[1]=>
float(1.1)
[2]=>
float(3.9)
}
$getID = array(3) {
[0]=>
string(1) "B"
[1]=>
string(1) "C"
[2]=>
string(1) "F"
}
I want to
array(3) {
[0]=> ["B", 2.2]
[1]=> ["C", 1.1]
[2]=> ["F", 3.9]
}
this is my code
function mergeArray($distance, $getID)
{
$mergeArray = array();
for ($i = 0; $i < count($distance); $i++) {
$mergeArray[] = array_splice($getID, $distance[$i]);
}
return $mergeArray;
}
Edited
help me please thx
You don't need "array_combine()", "array_slice()" or similar. Just iterate through the data and create a new one:
$a = [2.2, 1.1, 3.9];
$b = ["B", "C", "F"];
$new = [];
foreach ($a as $index => $value) {
$new[] = [
$b[$index], // Fetch the value with the same index from the other array
$value
];
}
Demo: https://3v4l.org/oseSV
You can use array_map to iterate over two arrays simultaneously and produce a new array:
$distance = array(3) {
[0]=>
float(2.2)
[1]=>
float(1.1)
[2]=>
float(3.9)
}
$getID = array(3) {
[0]=>
string(1) "B"
[1]=>
string(1) "C"
[2]=>
string(1) "F"
}
$output = array_map(function ($d, $id) {
return [$id, $d];
}, $distance, $getID);
Note that this code assumes that both arrays have the same length.
Offtopic:
A little advice about your code: always name your variable with something that allows you to know what's inside it, using correct plural too:
Your $distance variable contains an array off distances, so it nsme should be in plural.
Your $getID is not a function, so it should not be called get, but just $Ids instead.
$distance = [ 2.2, 1.1, 3.9 ];
$getID = [ "B", "C", "F" ];
$result = array_map(fn(string $id, float $distance) => [ $id, $distance ], $getID, $distance);
print_r($result);
For your current code to work you have to:
pass both elements to array_splice function as an array
pass the offset of where the function need to replace the value
as well as the number of how many elements should be removed
You should not reassign $mergeArray because array_splice work with pointer
Checkout the docs for more!
function mergeArray($distance, $getID)
{
$mergeArray = [];
for ($i = 0; $i < count($distance); $i++) {
array_splice($mergeArray,$i,1, [[
$distance[$i],
$getID[$i]
]]);
}
return $mergeArray;
}
however a better approach is to do as in M. Eriksson's ansewar.
Related
I got some array inside array and I want to get all the value of that and store it on variable. This is the structure of my array :
array(5) { ["InventoryID"]=> string(2) "43"
["Price"]=> string(5) "45.36"
["Warehouse"]=> array(2) { ["WID"]=> string(1) "1"
["Quantity"]=> string(1) "12"
}
["Name"]=> string(48) "Bottle"
["SKU"]=> string(8) "M123"
}
array(5) { ["InventoryID"]=> string(2) "51"
["Price"]=> string(5) "21.67"
["Warehouse"]=> array(2) { ["WID"]=> string(1) "1"
["Quantity"]=> string(1) "40"
}
["Name"]=> string(48) "Glass"
["SKU"]=> string(8) "M124"
}
What I want is to get all the value of that array and store it in variable like this :
$inventoryid = 43;
$price = 45.36;
$wid = 1;
$quantity = 12;
$name = 'Bottle';
$sku = 'M123';
What I do till now is I looping that array in foreach but I can't get the second array value. This is what I do till now :
foreach($array as $row)
{
$inventoryid = $row['InventoryID'];
$price = $row['Price'];
$name = $row['Name'];
$sku = $row['SKU'];
foreach($row['Warehouse'] as $row2)
{
$wid = $row2['WID'];
$quantity = $row2['Quantity'];
}
}
How can I do that ? Please anyone give me some code example with foreach to get the value.
I'm struggling to fully understand what benefit you're getting from having these values as variables rather than part of an array. You're still able to access the values quite easily.
Anyway, based on your comment it appears the issue is with the nested array. You don't need a foreach to access those values.
Example:
$wid = $row['Warehouse']['WID'];
$quantity = $row['Warehouse']['Quantity']
Documentation: http://php.net/manual/en/language.types.array.php
you can use recursive for this.
class ProductData
{
public function walkRecursive($a) {
asort($a); //Sort top down
foreach($a as $k => $v){
if(is_array($v)){
$this->walkRecursive($v);
}else{
$this->{$k} = $v;
}
}
return $this;
}
}
$array = array(
"SKU" => "Test1",
"Warehouse" => array("WID" => 1, "Quantity" => 2),
"Name" => "Product1"
);
$d = new ProductData();
$product = $d->walkRecursive($array);
You can now do: $product->SKU. Or $product->Quantity or $Product->Name
I have a database with multiple records. It is structured like this:
["data"]=>
array(5) {
[1]=>
[2]=>
array(11) {
[0]=>
string(1) "0"
[1]=>
string(8) "25000000"
[2]=>
string(3) "day"
[3]=>
string(5) "0.00%"
[4]=>
string(9) "404049904"
[5]=>
string(1) "0"
[6]=>
string(5) "0.00%"
[7]=>
string(1) "0"
[8]=>
string(1) "0"
[9]=>
string(1) "0"
[10]=>
string(3) "0.0"
}
I need to fetch the 8th record and I do this by using
public static function($data)
{
$array = [];
$path = $data->data[2];
foreach($path as $key => $item)
if($key > 1)
{
$array[] = [$item->data[8]];
}
return json_encode($array);
}
This foreach takes all the 8th values from the array but I need to display a single number which is the average of all the 8th values. How can I do this?
Once you've got your array containing all your data, simple sum the array and then divide by the size of the array.. something along these lines
$average = (array_sum($array) / count($array));
Of course you may want to check for count($array) being 0;
Because you put your value into a new array, you can not use array_sum to sum the values, so you should store it.
$sum = 0;
foreach($path as $key => $item)
if($key > 1) {
$array[] = [$item->data[8]];
$sum += $item->data[8];
}
}
$avg = ($sum / count($array); //the average
var_dump($avg);
If is it possible, just put it as a value:
$array[] = $item->data[8]; //no wrapping []
In this case, you can use $avg = array_sum($array) / count($array);
if (count($array)>0){
$avg = array_sum($array) / count($array);
}
I would personally do those calculations in the database before the data gets to your PHP script itself. See AVG().
If you can't for some reason use that I would output those values into a flat array and then just calculate the average. So something like :
function getAverage($data) {
$flatArray = array();
foreach ($data as $row) {
if (!empty($row->8)) {
$flatArray[] = $row->8;
}
}
return (array_sum($flatArray)/count($flatArray));
}
EDIT: Moved to Object traversing on the data row, sorry, missed that initially and thought it was an array in all the nests.
Since you have a loop within your static Method; why not do the calculation therein and return it or add it to the JSON Data if You need your Data in JSON Format? Here's what's implied by the above:
public static function getAverageSum($data) {
$array = [];
$path = $data->data[2];
$sumTotal = 0.00; //<== YOU COULD JUST SUM IT DIRECTLY WITHOUT USING AN ARRAY
foreach($path as $key => $item) {
if ($key > 1) {
$array[] = $item->data[8];
$sumTotal += floatval($item->data[8]);
}
}
// IF YOU ARE ONLY INTERESTED IN THE AVERAGE SUM YOU COULD EVEN ADD IT IT TO THE $array AS AN EXTRA KEY
// LIKE SO:
$arrLen = count($array);
$array['avgSum'] = $sumTotal/$arrLen;
// IF YOU NEED YOUR DATA IN JSON... THEN RETURN THE JSON ENCODED DATA WITH SUM AS PART OF THE DATA.
// YOU'D HAVE NO NEED FOR array_sum() SINCE YOU DID YOUR PREP-WORK ALREADY...
return json_encode($array);
// ALTERNATIVELY; IF ALL YOU NEED IS JUST THE AVERAGE SUM; YOU COULD AS WELL DIRECTLY RETURN $sumTotal/$arrLen
return ($sumTotal/$arrLen);
}
I have seen the following: array_merge() How can I add a 'range' of an array name and the answers don't work for me.
I have an array that I am looping through in order to slice and convert certain currency strings to float numbers. I then have to array_merge them back together in order to work with the array and have been dynamically naming them so that I don't overwrite the previous array_merge. After doing so, I then need to combine all of the dynamically named arrays into one array.
Initially I had the following code, which worked great when I only had 3 nested arrays in the $order['product'] array. However, this number varies, and the code needs to do so as well.
$nr = 1;
foreach ($order['product'] as $product) {
$product_total = array_slice($product, 1);
array_walk($product_total, "convertCurrencyStringtoNumber");
${"final_product" . $nr} = array_merge($product, $product_total);
$nr++;
};
$arrays = array($final_product1, $final_product2, $final_product3);
var_dump($arrays);
This results in the following array:
array(3) {
[0]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(18) }
[1]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(17) }
[2]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(2.75) } }
How do I implement a varied number of dynamically named arrays in the line:
$arrays = array($final_product1, $final_product2, $final_product3);
I attempted the following, but the array is nested incorrectly. Feel free to fix this code or come up with a better solution.
$nr = 1;
$i = 1;
foreach ($order['product'] as $product) {
$product_total = array_slice($product, 1);
array_walk($product_total, "convertCurrencyStringtoNumber");
${"final_product" . $nr} = array_merge($product, $product_total);
if ($nr > 0) {
$arrays = $final_product1;
for ($i = 2; $i <= $nr; $i++) {
$arrays = array_merge($arrays, ${"final_product" . $nr});
}
} else {
echo "There are no products in this order";
}
$nr++;
};
var_dump($arrays);
This results in the incorrectly nested array:
array(2) {
[0]=> array(2) {
[0]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(18) }
[1]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(17) } }
[1]=> array(2) {
["source_code"]=> string(10) "408000-025"
["total"]=> float(2.75) } }
Simply replace your dynamically single-named variables with an array:
$final_product = array();
foreach ($order['product'] as $product) {
$product_total = array_slice($product, 1);
array_walk($product_total, "convertCurrencyStringtoNumber");
$final_product[] = array_merge($product, $product_total);
};
var_dump($final_product);
Unless I'm missing something here... this should be as easy and simple as:
$final_array=[];
foreach ($order['product'] as $product) {
$final_array[]['total'] = (float) $product['whatever value 1 is...'];
$final_array[]['source_code'] = $product['source_code'];
}
var_dump($final_array);
If you need to apply convertCurrencyStringtoNumberbecause it does something weird to the variable then changethe seccond line to:
$final_array[]['total'] = convertCurrencyStringtoNumber(array_slice($product, 1));
I'm trying to compare 2 Arrays and output the difference in a separate array.
I've made the following line of code to compare 2 Arrays;
$INPUTdifference = array_udiff($userINPUT, $iptablesINPUT, function ($userINPUT, $iptablesINPUT) { return (int) ($userINPUT != $iptablesINPUT); });
When userINPUT contains one row for testing, and iptablesINPUT a few, it works flawlessly.
However, whenever I add a second row in the userINPUT array, it completely stops working. It doesn't even give anything while I print the INPUTdifference anymore
What is wrong here?
EDIT;
The way userINPUT is acquired;
function getIPTablesINPUT() {
/* ------------------------------ */
// INPUT CHAIN
/* ------------------------------ */
$INPUTCOMMAND = popen('/usr/bin/sudo /sbin/iptables -L INPUT -nvx --line-numbers | tail -n +3', 'r');
$INPUTcontent = '';
while (!feof($INPUTCOMMAND)) {
$INPUTcontent .= fread($INPUTCOMMAND, 4096);
}
pclose($INPUTCOMMAND);
$INPUTlines = explode("\n", trim($INPUTcontent));
$INPUTresults = array();
$INPUTcounter = 0;
foreach ($INPUTlines as $line) {
$segments = preg_split('/[\s]+/', $line);
$INPUTArray = array(
'num' => $segments[0],
'pkts' => $segments[1],
'bytes' => $segments[2],
'target' => $segments[3],
'prot' => $segments[4],
'opt' => $segments[5],
'in' => $segments[6],
'out' => $segments[7],
'source' => $segments[8],
'destination' => $segments[9]
);
array_push($INPUTresults, $INPUTArray);
$INPUTcounter++;
}
return $INPUTresults;
}
then, outside of the function
$iptablesINPUT = getIPTablesINPUT();
Then, the way the rules in the data
$dbconnection = pg_connect("host=x port=x dbname=x user=x password=xxxx") or die("Unable to connect to Postgres");
// INPUT table from userDB
$userINPUTresult = pg_query($dbconnection, "SELECT * FROM \"INPUT\"");
if (pg_affected_rows($userINPUTresult) === 1) {
$userINPUTArray = pg_fetch_all($userINPUTresult);
echo "INPUT CHAIN RULES LOADED \n";
} else {
echo ("NO INPUT CHAIN RULES \n");
}
==== VAR DUMPS ====
var_dump $iptablesINPUT
NULL
array(2) {
[0]=>
array(10) {
["num"]=>
string(1) "1"
["pkts"]=>
string(1) "0"
["bytes"]=>
string(1) "0"
["target"]=>
string(4) "DROP"
["prot"]=>
string(3) "all"
["opt"]=>
string(2) "--"
["in"]=>
string(1) "*"
["out"]=>
string(1) "*"
["source"]=>
string(9) "192.0.0.1"
["destination"]=>
string(9) "0.0.0.0/0"
}
[1]=>
array(10) {
["num"]=>
string(1) "2"
["pkts"]=>
string(1) "0"
["bytes"]=>
string(1) "0"
["target"]=>
string(4) "DROP"
["prot"]=>
string(3) "all"
["opt"]=>
string(2) "--"
["in"]=>
string(1) "*"
["out"]=>
string(1) "*"
["source"]=>
string(9) "192.0.0.2"
["destination"]=>
string(9) "0.0.0.0/0"
}
}
var_dump $userINPUT
NULL
Apparentely this is the spot where something goes wrong...
==== EDIT 2 ======
This is the way I extract the arrays from the function out of the scope.
// Slice up userDB arrays for comparing
$userINPUT = $allRules[0];
$userOUTPUT = $allRules[1];
$userFORWARD = $allRules[2];
$userPOSTROUTING = $allRules[3];
$userPREROUTING = $allRules[4];
The array_udiff function returns you the elements which are in the first array and are not in the next arrays.
From array_udiff page:
array array_udiff ( array $array1 , array $array2 [, array $... ], callable $value_compare_func )
Returns an array containing all the values of array1 that are not present in any of the other arguments
Since the value of your first array ($userINPUT in your case) is null then the result of array_udiff will be also null.
Look, after execution of the following code
$a = array(1,2);
$b = array(1);
$c = array_udiff($a, $b, function($a, $b){return (int) $a != $b;});
// $c == array(2) now
the value of $c will be array(2), since the following code
$a = null;
$b = array(1);
$c = array_udiff($a, $b, function($a, $b){return (int) $a != $b;});
// $c == null now
will lead to $c equals null.
I have an array that groups different items by item type. I am grouping the result by category_id field. What I want is the output to be
item1 = 3
item2 = 2
My array looks like this if I do a var_dump()
array(2) {
["item1"]=>
array(3) {
[0]=>
string(1) "3"
[2]=>
string(1) "5"
[4]=>
string(1) "7"
}
["item2"]=>
array(2) {
[1]=>
string(1) "4"
[3]=>
string(1) "6"
}
}
Here is the code I am using:
$items = Item::where('order_id','=',$payload["orderId"])->get();
$itemsGrouped = [];
$count = 0;
foreach($items as $item){
$itemsGrouped[$item->category_id][$count] = $item->id;
$count++;
}
foreach($itemsGrouped as $grp){
echo key($itemsGrouped).'='.count($grp).'<br>';
};
And here is what I am currently getting. The count is working but not the $itemsGrouped key. It is duplicated.
item2=3<br>item2=2<br>
Change your code as below
foreach($itemsGrouped as $key => $grp){
echo $key.'='.count($grp).'<br>';
};
In order to use key() function, you need to traverse the array using next/current function
foreach($itemsGrouped as $key => $grp){
echo $key.'='.count($grp).'<br>';
};
key() function returns the current element's key, which is defined by an array's internal pointer. Obviously it always points to the last element.
$myarray = "Your array";
$count = array(); // create an empty array
foreach($myarray as $arr) {
foreach($arr as $a) {
$key = array_keys($a);
$count[$key[0]]++;
}
}
print_r($count);