How to count more than one items in array_column? - php

I asked a question called 'How to count items in an array that's in an array?' and now I need help on expanding from that question.
How do you count items in two arrays?
My array looks like this:
Array
(
[0] => Array
(
[acf_fc_layout] => irl_today_website_entry
[irl_today_website] => Array
(
[0] => Array
( data removed)
[1] => Array
( data removed )
)
)
[1] => Array
(
[acf_fc_layout] => irl_today_social_entry
[irl_today_social] => Array
(
[0] => Array
( data remove )
[1] => Array
( data remove)
)
)
)
And I use:
<?php $arrays = get_field('irl_today_entry');
$res = array_map(function($x) {
return count($x);
}, array_column($arrays, 'irl_today_website'));?>
to count items in [irl_today_social]. How do I count items in [irl_today_social] and [irl_today_website]?
I tried array_column($arrays, "irl_today_social", "irl_today_website") and it only counted items in [irl_today_social]

array_map() can be fed multiple arrays to work with. The first array "irl_today_social" elements are referenced by $x, the second "irl_today_website" by $y in this case.
Use following:
$res = array_map(function($x, $y) {
$soc = count($x);
$web = count($y);
return ['soc' => $soc, 'web' => $web];
}, array_column($arrays, "irl_today_social"), array_column($arrays, "irl_today_website"));
array_map() will return an array with the count for each - the result sample output:
Array
(
[0] => Array
(
[soc] => 2
[web] => 3
)
)
demo

Related

Convert comma separated array to nested array with php function

I need to convert array_1 to array_2 with a PHP function. I tried many things but nothing works. I hope someone can help me out here. I think I need an each function or something to loop through the comma separated array and convert it into the array_2.
$array_1 = array (
0 => '6801,6800,7310,6795',
);
$array_2 = array (
0 =>
array (
0 => '6801',
1 => '6800',
2 => '7310',
3 => '6795',
),
);
Here a solution
<?php
$array_1 = array (
0 => '6801,6800,7310,6795',
);
$array_2 = array();
foreach ($array_1 as $value) {
array_push($array_2 , explode(",",$value));
}
print_r($array_2);
?>
The output that i got
Array ( [0] => Array ( [0] => 6801 [1] => 6800 [2] => 7310 [3] => 6795 ) )
Use PHP explode function. https://www.php.net/manual/de/function.explode.php
$newArray[] = explode(",", $array_1[0]);
// output
Array
(
[0] => Array
(
[0] => 6801
[1] => 6800
[2] => 7310
[3] => 6795
)
)
Just create a new array with a value returned by the explode function. Reset always returns the first value of the array regardless of the key.
$array_1 = array (0 => '6801,6800,7310,6795');
$newArray = [explode(",", reset($array_1))];

How to merge two arrays based on their index php?

I need to merge 2 arrays and i have found lot of examples here on stackoverflow, but nothing has worked for me, in my case, so i explain my case:
Arrays (can be one, two, or three, or more...):
Array ( [0] => name-file_icon_001_00.png-
[1] => name-file_icon_002_00.png-
[2] => name-file_icon_003_00.png- )
Array ( [0] => rel
[1] => rel
[2] => rel )
Or can be two:
Array ( [0] => name-file_icon_001_00.png-
[1] => name-file_icon_002_00.png- )
Array ( [0] => rel
[1] => rel )
Or one:
Array ( [0] => name-file_icon_001_00.png- )
Array ( [0] => rel )
Need to insert the relative value "[0] => rel" with "[0] => name-file_icon_001_00.png-"
Expected result (merged):
Array ( [0] => name-file_icon_001_00.png-rel
[1] => name-file_icon_002_00.png-rel
[2] => name-file_icon_003_00.png-rel )
Reading around the web, seems that not exist a native function for make this.
Please, hope in your help :)
A simple foreach loop using the index and value parameters will do it in no time
Example
$a1 = ['name-file_icon_001_00.png-',
'name-file_icon_002_00.png-',
'name-file_icon_003_00.png-'
];
$a2 = ['rel1','rel2','rel3'];
foreach ($a1 as $i => $v){
$new[] = $v . $a2[$i];
}
print_r($new);
RESULT
Array
(
[0] => name-file_icon_001_00.png-rel1
[1] => name-file_icon_002_00.png-rel2
[2] => name-file_icon_003_00.png-rel3
)
You can map each array to a function that concatenates them:
$result = array_map(function($a, $b) { return $a.$b; }, $one, $two);
If you define one array with subarrays then you can unpack that array ...:
$array = [$one, $two];
$result = array_map(function($a, $b) { return $a.$b; }, ...$array);
Or for fun, you can extract each column from the subarrays and implode them:
$array = [$one, $two];
for($i=0; $a=array_column($array, $i); $i++) {
$result[] = implode($a);
}

PHP Create a Nested Array with indexes from a CSV file

I'm having a peculiar issue. I have a CSV file that has Comma Separated Values that I need to upload and then get Nested Array of values based on following 3 conditions;
The array will first loop through all values and get first 4 unique
characters. (Codes)
Match each column values with the with number of
columns in each row and give count of rows that matches 4 digit
codes. (Single_Devices for single column and Dual, Triple and Quad for respective columns count)
Match each column values with code and list all the
columns under the Devices. (Numbers)
CSV file
123429000000000
123429000000001
123429000000010,123429000000011
123429000000040,123429000000041
What I desire is;
Array
(
[Code] => 1234
(
[single_devices] => 2
(
[0] => Array
(
[0] => 123429000000000
)
[1] => Array
(
[0] => 123429000000001
)
)
[dual_devices] => 2
(
[0] => Array
(
[0] => 123429000000010
[1] => 123429000000011
)
[1] => Array
(
[0] => 123429000000040
[1] => 123429000000041
)
)
)
)
Is it possible?
I can manage JSON converted data or object or just associative nested array.
Edit: This is the code I wrote for which was only showing values and not indexes as I desired.
// Get all numbers in array
for ($j = 0; $j < count($csv_file[$i]); $j++){
$numbers[] = $csv_file[$i][$j];
}
// Get codes from numbers
for ($i = 0; $i < count($csv_file); $i++){
for ($j = 0; $j < count($csv_file[$i]); $j++){
$codes[] = substr($csv_file[$i][$j], 0, 4);
}
}
// Get unique codes from codes array
$codes = array_unique($codes);
// Get numbers and sort them codes and device count wise.
for ($i = 0; $i < count($csv_file); $i++){
for ($j = 0; $j < count($csv_file[$i]); $j++){
$q = count($csv_file[$i]); // set device count based on column count
if (count($csv_file[$i]) == $q){ // if device count is equal to column count
foreach ($codes as $code){ // loop through unique codes
if ($code == substr($csv_file[$i][$j], 0, 4)){ // if number's first 4 char matches code
// create array with code and then device count and add numbers
$devices[$code][$q.'_device_numbers'][$i][$j] = preg_replace('/\s+/', '', $csv_file[$i][$j]);
}
}
}
}
}
This is what I am getting from the above code.
Array
(
[1234] => Array
(
[1_sim_imeis] => Array
(
[0] => Array
(
[0] => 123429000000000
)
[1] => Array
(
[0] => 123429000000001
)
)
[2_sim_imeis] => Array
(
[2] => Array
(
[0] => 123429000000010
[1] => 123429000000011
)
[3] => Array
(
[0] => 123429000000040
[1] => 123429000000041
)
)
)
)
This is based on reading the file as a csv (using fgetcsv()) and extracting the first 4 digits of the first value on each line. It then uses another array to give the key for the 'single_devices' etc. key - using the count of the number of elements on the line (-1 as the array is 0 based)...
$fileName = "a.dat";
$output = [];
$baseData = [ 'single_devices', 'dual_devices', 'triple_devices', 'quad_devices' ];
$fh = fopen ( $fileName, "r" );
while ( ($data = fgetcsv($fh)) !== false ) {
$code = substr($data[0], 0, 4);
$output[$code][$baseData[count($data)-1]][] = $data;
}
fclose($fh);
print_r($output);
which with the test data gives...
Array
(
[1234] => Array
(
[single_devices] => Array
(
[0] => Array
(
[0] => 123429000000000
)
[1] => Array
(
[0] => 123429000000001
)
)
[dual_devices] => Array
(
[0] => Array
(
[0] => 123429000000010
[1] => 123429000000011
)
[1] => Array
(
[0] => 123429000000040
[1] => 123429000000041
)
)
)
With
while ( ($data = fgetcsv($fh)) !== false ) {
$code = substr($data[0], 0, 4);
if ( !isset($output[$code])) {
$output[$code] = ["code" => $code];
}
$deviceLabel = $baseData[count($data)-1];
$output[$code][$deviceLabel]['count'] =
($output[$code][$deviceLabel]['count'] ?? 0) + 1;
$output[$code][$deviceLabel][] = $data;
}
you can get an output of...
Array
(
[1234] => Array
(
[code] => 1234
[single_devices] => Array
(
[count] => 2
[0] => Array
(
[0] => 123429000000000
)
[1] => Array
(
[0] => 123429000000001
)
)

Looping through and clearing arrays

I have arrays within arrays, all with varying amounts of information. My CSV table currently has the fields Name, Email, and Phone Number.
Below is my array;
Array
(
[0] => Array
(
[0] => Name
[1] => Email
[2] => Phone Number
)
[1] => Array
(
[0] => Mick
[1] => mick#mick.com
[2] => 01234 324234
)
[2] => Array
(
[0] => james
[1] => james#james.com
[2] =>
)
[3] => Array
(
[0] => reg
[1] => reg#reg.com
[2] => 10293 467289
)
)
I wish to loop through and remove these null values and combine the Email and Phone Number into Info end up with an array which resembles
Array
(
[0] => Array
(
[0] => Name
[1] => Info
)
[1] => Array
(
[0] => Mick
[1] => mick#mick.com + 01234 324234
)
[2] => Array
(
[0] => james
[1] => james#james.com
)
[3] => Array
(
[0] => reg
[1] => reg#reg.com + 10293 467289
)
)
Here is my current script, I am recienving the error;
<b>Warning</b>: array_filter() expects parameter 2 to be a valid callback, no array or string given in <b>C:\Users\Lydia\Documents\XAMPP\htdocs\CSV.php</b> on line <b>21</b><br />
every time that I loop through the changeRow() function, any help greatly appreciated
index.php
<?php
include 'CSV.php';
header('Content-type: text/plain');
$file = read_csv('Book1.csv');
$input = changeRow($file);
CSV.php
....
....
function changeRow($rows){
$len = count($rows);
for($i = 0; $i < $len; $i++){
$rows = array_filter($rows[0],0);
}
}
Can use array_map() instead of foreach(). Example:
$file = read_csv('Book1.csv');
$input = array_map(function($v){
$phone = (isset($v[2]) && $v[2]) ? ' + '. $v[2] : '';
return array($v[0], $phone);
},$file );
if(isset($result[0][1])) $result[0][1] = 'Info';
print '<pre>';
print_r($input);
print '</pre>';
I'll provide two methods that output the requested array structure. (PHP Demo Link) These methods iterate the array, check if the iteration is dealing with the "column heading" subarray or not, then conditionally appending the value from subarray element [2] to subarray element [1] using + as glue.
Method #1: foreach()
foreach($array as $index=>$item){
if(!$index){
$result[]=['Name','Info'];
}else{
$result[]=[$item[0],$item[1].(strlen($item[2])?" + $item[2]":'')];
}
}
var_export($result);
Method #2 array_map()
var_export(
array_map(function($index,$item){
if(!$index){
return ['Name','Info'];
}else{
return [$item[0],$item[1].(strlen($item[2])?" + $item[2]":'')];
}
},array_keys($array),$array)
);
Output: (from either method)
array (
0 =>
array (
0 => 'Name',
1 => 'Info',
),
1 =>
array (
0 => 'Mick',
1 => 'mick#mick.com + 01234 324234',
),
2 =>
array (
0 => 'james',
1 => 'james#james.com',
),
3 =>
array (
0 => 'reg',
1 => 'reg#reg.com + 10293 467289',
),
)
ps. If you want to remove the $index==0 check that is iterated each time, you can manually overwrite the first subarray after the loop is finished like this: (PHP Demo Link) *this just means you will be "writing" data to the first subarray twice.
foreach($array as $item){
$result[]=[$item[0],$item[1].(strlen($item[2])?" + $item[2]":'')];
}
$result[0]=['Name','Info'];
var_export($result);
or
$result=array_map(function($item){return [$item[0],$item[1].(strlen($item[2])?" + $item[2]":'')];},$array);
$result[0]=['Name','Info'];
var_export($result);
pps. "Passing by Reference" can be used for this task, but I've elected not to use &$array because it can risk causing trouble "downscript" and many developers advise against using it until other methods are inadequate. Here is what that can look like: (PHP Demo Link)
foreach($array as &$item){
if(strlen($item[2])) $item[1].=" + $item[2]";
unset($item[2]);
}
$array[0]=['Name','Info'];
var_export($array);
unset($item); // var_export($item); // ($item = NULL)

max() on multidimensional array

I've got an array of input data and I need to find the max and min values. The POST array could look like any of the following, depending on the options the user selected:
[a] => Array
(
[0] => 2
)
[a] => Array
(
[0] => 2
[1] => 4
[2] => 7
)
[a] => Array
(
[0] => 2
[1] => 4
[2] => Array
(
[0] => 7
)
)
I had it working by sorting the array and grab the min and max values when 'a' was always a single-dimensional array, but since we've added the option for it to be multidimensional I'm stuck.
I would use an Iterator: http://php.net/spl.iterators.php
function array_max($arr) {
$max = null;
foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)) as $value) {
if ($max === null || $value > $max) {
$max = $value;
}
}
return $max;
}
I think you can figure out how to do array_min() on your own.

Categories