$cnt[0]=>Array( [0] => 0 [1] => 0 [2] => 0 ),
$cnt[1] => Array ( [0] => 1 [1] => 0 [2] => 0 )
i want convert this array to below result,
$cnt[0]=(0,0);
$cnt[1]=(0,0);
$cnt[2]=(0,1);
any php function there to convert like this format,
Thanks,
Nithish.
function flip($arr)
{
$out = array();
foreach ($arr as $key => $subarr)
{
foreach ($subarr as $subkey => $subvalue)
{
$out[$subkey][$key] = $subvalue;
}
}
return $out;
}
see more example in
PHP - how to flip the rows and columns of a 2D array
I'm interpreting your expected output to be something like a list of pairs:
$pairs = array(
array(1,0),
array(0,0),
array(0,0)
);
You'd simply check that the sub-arrays are the same length, and then use a for loop:
assert('count($cnt[0]) == count($cnt[1])');
$pairs = array();
for ($i = 0; $i < count($cnt[0]); ++$i)
$pairs[] = array($cnt[0][$i], $cnt[1][$i]);
Related
I have the following working code that from 2 separate arrays ($I & $f) creates final multidimension array with the data as associated columns.
The problem is i feel the code is clunky, but i cant see if, or how it could me improved. So I'm hoping a second pair of eyes can help.
<?php
//main array of input data
$i = [ 'input_tickettype1_storeno_00' => null,
'input_tickettype1_deliverydate_00' => null,
'input_tickettype1_ticketref_00' => null,
'input_tickettype1_storeno_01' => '9874',
'input_tickettype1_deliverydate_01' => '2022-02-01',
'input_tickettype1_ticketref_01' => 'EDN6547',
'input_tickettype1_storeno_02' => '8547',
'input_tickettype1_deliverydate_02' => '2022-01-31',
'input_tickettype1_ticketref_02' => 'EDN5473',
'input_tickettype1_storeno_03' => '9214',
'input_tickettype1_deliverydate_03' => '2022-02-28',
'input_tickettype1_ticketref_03' => 'EDN1073'
];
//headers
$h = [ 'input_tickettype1_storeno' ,
'input_tickettype1_deliverydate',
'input_tickettype1_ticketref'
];
//final multidim array
$f = array();
//Create a multidim for the headers and the values
foreach ($h as $k => $v)
{
$f[] = [$v=>null];
}
//loop throught the headers looping for matches in the input data
for ($x = 0; $x < count($f); $x++) {
foreach ($f[$x] as $fk => $fv) {
foreach ($i as $ik => $iv) {
if (str_contains($ik,$fk)) {
array_push($f[$x],$iv);
}
}
}
}
print_r($f);
//Actual Working Output
// Array (
// [0] => Array ( [input_tickettype1_storeno] =>
// [0] =>
// [1] => 9874
// [2] => 8547
// [3] => 9214
// )
// [1] => Array ( [input_tickettype1_deliverydate] =>
// [0] =>
// [1] => 2022-02-01
// [2] => 2022-01-31
// [3] => 2022-02-28
// )
// [2] => Array ( [input_tickettype1_ticketref] =>
// [0] =>
// [1] => EDN6547
// [2] => EDN5473
// [3] => EDN1073
// )
// )
?>
Yes, indeed I think the code can be optimised for readability and logic.
I can think of two methods you can use.
Method 1 : nested foreach
First of all, you don't need a foreach to initialize your multidimentional array, you can do it within the main loop you use to read the data. So you can remove the foreach -- $f[] = [$v=>null];
Then, instead of having 1 for and 2 foreach you can just have 2 foreach one for each array and use a very fast strpos to identify if the key matches and populate the final array.
Here's the resulting code.
$f = [];
foreach ($h as $prefix) {
$f[$prefix] = [];
foreach ($i as $key => $val) {
if (strpos($key, $prefix) === 0) {
$f[$prefix][] = $val;
}
}
}
This first method is simple, with a straightforward logic. However it requires a nested foreach. Which means that if both arrays get larger, your code gets much slower.
Method 2 : key manipulation
This method assumes that the keys of the first array never change structure and they are always somestringid_[digits]
In this case we can avoid looping the second array and just use a regular expression to recreate the key.
$f = [];
foreach ($i as $key => $value) {
preg_match('/^(.*)_[0-9]+$/', $key, $m);
$key = $m[1];
if (empty($f[$m[1]])) {
$f[$m[1]] = [];
}
$f[$m[1]][] = $value;
}
I don't see any need to implement any additional data or conditions. You only need to read your main array, mutate the keys (trim the trailing unique identifiers) as you iterate, and push data into their relative groups.
Code: (Demo)
$result = [];
foreach ($array as $k => $v) {
$result[preg_replace('/_\d+$/', '', $k)][] = $v;
}
var_export($result);
Output:
array (
'input_tickettype1_storeno' =>
array (
0 => NULL,
1 => '9874',
2 => '8547',
3 => '9214',
),
'input_tickettype1_deliverydate' =>
array (
0 => NULL,
1 => '2022-02-01',
2 => '2022-01-31',
3 => '2022-02-28',
),
'input_tickettype1_ticketref' =>
array (
0 => NULL,
1 => 'EDN6547',
2 => 'EDN5473',
3 => 'EDN1073',
),
)
So say I have an array below. As an example, is it possible in PHP to replace the -2.7 value of the first array part to 100 without knowing the #RR key or #BR for the other part? Such as:
$array[8314][WILDCARD][-1] = 100;
Array
(
[8314] => Array
(
[#RR] => Array
(
[-1] => -2.7
[0] => 0
)
)
[8810] => Array
(
[#BR] => Array
(
[-1] => 32500
[0] => 0
)
)
)
I think that you are looking for the below solution using array_key_first:
$firstKey = array_key_first($array); //say we found 8314;
$WILDCARD = array_key_first($array[$firstKey]);
//replace the old value with 100;
$array[$firstKey][$WILDCARD][-1] = 100;
Yes:
foreach ($input as $outerKey => $outerValue) {
foreach ($outerValue as $innerKey => $innerValue) {
foreach ($innerValue as $key => $value) {
if ($value === 2.7) $input[$outerKey][$innerKey][$key] = 100;
}
}
}
The code above assumes that you want to change 2.7 => 100 for all elements. If, instead of that you need to do it just for the first, then:
$visited = false;
foreach ($outerValue as $innerKey => $innerValue) {
if ($visited) break;
$visited = true;
foreach ($innerValue as $key => $value) {
if ($value === 2.7) $input[$outerKey][$innerKey][$key] = 100;
}
}
I have an array which as dynamic nested indexes in e.g. I am just using 2 nested indexes.
Array
(
[0] => Array
(
[0] => 41373
[1] => 41371
[2] => 41369
[3] => 41370
)
[1] => Array
(
[0] => 41378
[1] => 41377
[2] => 41376
[3] => 41375
)
)
Now I want to create a single array like below. This will have 1st index of first array then 1st index of 2nd array, 2nd index of first array then 2nd index of 2nd array, and so on. See below
array(
[0] =>41373
[1] => 41378
[2] => 41371
[3] => 41377
[4] => 41369
[5] => 41376
[6] => 41370
[7] => 41375
)
You can do something like this:
$results = [];
$array = [[1,2,3,4], [1,2,3,4], [1,2,3,4]];
$count = 1;
$size = count($array)-1;
foreach ($array[0] as $key => $value)
{
$results[] = $value;
while($count <= $size)
{
$results[] = $array[$count][$key];
$count++;
}
$count = 1;
}
I think you need something like this:
function dd(array $arrays): array
{
$bufferArray = [];
foreach($arrays as $array) {
$bufferArray = array_merge_recursive($bufferArray, $array);
}
return $bufferArray;
}
$array1 = ['41373','41371','41369','41370'];
$array2 = ['41378','41377', '41376', '41375'];
$return = array();
$count = count($array1)+count($array2);
for($i=0;$i<($count);$i++){
if($i%2==1){
array_push($return, array_shift($array1));
}
else {
array_push($return, array_shift($array2));
}
}
print_r($return);
first count the arrays in the given array, then count the elements in the first array, than loop over that. All arrays should have the same length, or the first one should be the longest.
$laArray = [
['41373','41371','41369','41370'],
['41378', '41377', '41376', '41375'],
['43378', '43377', '43376', '43375'],
];
$lnNested = count($laArray);
$lnElements = count($laArray[0]);
$laResult = [];
for($lnOuter = 0;$lnOuter < $lnElements; $lnOuter++) {
for($lnInner = 0; $lnInner < $lnNested; $lnInner++) {
if(isset($laArray[$lnInner][$lnOuter])) {
$laResult[] = $laArray[$lnInner][$lnOuter];
}
}
}
this would be the simplest solution:
$firstarr = ['41373','41371','41369','41370'];
$secondarr = ['41378','41377','41376','41375'];
$allcounged = count($firstarr)+count($secondarr);
$dividedintotwo = $allcounged/2;
$i = 0;
while ($i<$dividedintotwo) {
echo $firstarr[$i]."<br>";
echo $secondarr[$i]."<br>";
$i++;
}
I have an array that looks something like this:
Array (
[0] => Array ( [country_percentage] => 5 %North America )
[1] => Array ( [country_percentage] => 0 %Latin America )
)
I want only numeric values from above array. I want my final array like this
Array (
[0] => Array ( [country_percentage] => 5)
[1] => Array ( [country_percentage] => 0)
)
How I achieve this using PHP?? Thanks in advance...
When the number is in first position you can int cast it like so:
$newArray = [];
foreach($array => $value) {
$newArray[] = (int)$value;
}
I guess you can loop the 2 dimensional array and use a preg_replace, i.e.:
for($i=0; $i < count($arrays); $i++){
$arrays[$i]['country_percentage'] = preg_replace( '/[^\d]/', '', $arrays[$i]['country_percentage'] );
}
Ideone Demo
Update Based on your comment:
for($i=0; $i < count($arrays); $i++){
if( preg_match( '/North America/', $arrays[$i]['country_percentage'] )){
echo preg_replace( '/[^\d]/', '', $arrays[$i]['country_percentage'] );
}
}
Try this:
$arr = array(array('country_percentage' => '5 %North America'),array("country_percentage"=>"0 %Latin America"));
$result = array();
foreach($arr as $array) {
$int = filter_var($array['country_percentage'], FILTER_SANITIZE_NUMBER_INT);
$result[] = array('country_percentage' => $int);
}
Try this one:-
$arr =[['country_percentage' => '5 %North America'],
['country_percentage' => '0 %Latin America']];
$res = [];
foreach ($arr as $key => $val) {
$res[]['country_percentage'] = (int)$val['country_percentage'];
}
echo '<pre>'; print_r($res);
output:-
Array
(
[0] => Array
(
[country_percentage] => 5
)
[1] => Array
(
[country_percentage] => 0
)
)
You can use array_walk_recursive to do away with the loop,
passing the first parameter of the callback as a reference to modify the initial array value.
Then just apply either filter_var or intval as already mentioned the other answers.
$array = [
["country_percentage" => "5 %North America"],
["country_percentage" => "0 %Latin America"]
];
array_walk_recursive($array, function(&$value,$key){
$value = filter_var($value,FILTER_SANITIZE_NUMBER_INT);
// or
$value = intval($value);
});
print_r($array);
Will output
Array
(
[0] => Array
(
[country_percentage] => 5
)
[1] => Array
(
[country_percentage] => 0
)
)
You could get all nemeric values by looping through the array. However I don't think this is the most efficient and good looking answer, I'll post it anyways.
// Array to hold just the numbers
$newArray = array();
// Loop through array
foreach ($array as $key => $value) {
// Check if the value is numeric
if (is_numeric($value)) {
$newArray[$key] = $value;
}
}
I missunderstood your question.
$newArray = array();
foreach ($array as $key => $value) {
foreach ($value as $subkey => $subvalue) {
$subvalue = trim(current(explode('%', $subvalue)));
$newArray[$key] = array($subkey => $subvalue);
}
}
If you want all but numeric values :
$array[] = array("country_percentage"=>"5 %North America");
$array[] = array("country_percentage"=>"3 %Latin America");
$newArray = [];
foreach ($array as $arr){
foreach($arr as $key1=>$arr1) {
$newArray[][$key1] = intval($arr1);
}
}
echo "<pre>";
print_R($newArray);
This is kind of a ghetto method to doing it cause I love using not as many pre made functions as possible. But this should work for you :D
$array = array('jack', 2, 5, 'gday!');
$new = array();
foreach ($array as $item) {
// IF Is numeric (each item from the array) will insert into new array called $new.
if (is_numeric($item)) { array_push($new, $item); }
}
I have 2 arrays in PHP. One of them holds a list of dates, the other a list of numbers.
Array1
(
[0] => 2010-06-14
[1] => 2010-06-14
[2] => 2010-06-14
[3] => 2014-01-26
[4] => 2014-01-26
)
Array2
(
[0] => 120
[1] => 100
[2] => 60
[3] => 140
[4] => 30
)
The value [0] in Array2 belongs with the date [0] in Array1. What I am trying to do is add all of the values in Array2 together, based on the date. Any dates that match should have their values added together. So for example at the end I would like something like:
$date = 2010-06-14;
$value = 280;
$date = 2014-01-26;
$value = 170;
...and so on.
I've searched though the site but was unable to find exactly what I needed. Any help would be appreciated...
You can iterate $values, and get the corresponding date from $dates to use as the key in your result array.
foreach ($values as $key => $value) {
$result[$dates[$key]] = $value + ($result[$dates[$key]] ?? 0);
}
The output will be like this:
array (size=2)
'2010-06-14' => int 280
'2014-01-26' => int 170
$sum=0; // New Element
$Array3[][]=0; // New 2D array
$p=0; // Counter for 2D array
for($i=0;$i<5;$i++) // Single loop for traversing
{
$date=Array1[$i]; // Start for a date
while($date==Array1[$i]){ // For for Similar date
$sum=$sum+Array2[$i]; // Adding values of similar date
$i++; // Increment array
}
$Array3[$p]["date"]=$date; // Array3 date element
$Array3[$p]["sum"]=$sum; // Array4 date element
$i--; // Reducing a value which is incremented in while loop
}
Array3 is like
Array3
(
[0] => array( 'date' => " ",'sum' => " ")
[1] => array( 'date' => " ",'sum' => " ")
)
Are you trying to count all of the values in Array2 that have an entry in Array1 that matches some predefined target value?
If so, this for loop version should work:
private function forLoopVersion($array1, $array2, $target) {
$result = 0;
for ($i = 0; $i < count($array1); ++$i) {
if ($array1[$i] == $target) {
$result += $array2[$i];
}
}
return $result;
}
Also, this foreach loop version might work, but I do not know if the $key for $array1 can be used to index an element in $array2. You could try it:
private function foreachLoopVersion($array1, $array2, $target) {
$result = 0;
foreach ($array1 as $key => $value) {
if ($value == $target) {
$result += $array2[$key];
}
}
return $result;
}
$newArray = array();
for($i = 0; $i < count(Array1); $i++) {
$newArray[$Array1[$i]] = $Array2[$i];
}
echo $newArray[$date1] + $newArray[$date2];
Put the dates as keys to for easy math.