I have an array with some string values
array(4) {
[0]=> array(2) { ["x"]=> string(13) "1475269218000" ["y"]=> string(1) "1" }
[1]=> array(2) { ["x"]=> string(13) "1475269222000" ["y"]=> string(1) "1" }
[2]=> array(2) { ["x"]=> string(13) "1475269231000" ["y"]=> string(1) "1" }
[3]=> array(2) { ["x"]=> string(13) "1475269241000" ["y"]=> string(1) "1" }
}
I need an output with only values as ints. So this would be the output.
[
[1475269218000,1],
[1475269222000,1],
[1475269231000,1]
[1475269241000,1]
]
Option 1:
$ar = [
['x' => '1475269218000', 'y' => '1'],
['x' => '1475269222000', 'y' => '1'],
['x' => '1475269231000', 'y' => '1'],
['x' => '1475269241000', 'y' => '1']
];
foreach($ar AS $key1 => $sub_ars) {
foreach($sub_ars AS $key2 => $val) {
$ar[$key1][$key2] = intval($val);
}
}
var_dump($ar);
Option 2:
$ar = [
['x' => '1475269218000', 'y' => '1'],
['x' => '1475269222000', 'y' => '1'],
['x' => '1475269231000', 'y' => '1'],
['x' => '1475269241000', 'y' => '1']
];
function intvalRecursive($val)
{
if(is_array($val)) {
return array_map('intvalRecursive', $val);
}
return intval($val);
}
$ar = array_map('intvalRecursive', $ar);
var_dump($ar);
Option 3 (stripping keys):
$ar = [
['x' => '1475269218000', 'y' => '1'],
['x' => '1475269222000', 'y' => '1'],
['x' => '1475269231000', 'y' => '1'],
['x' => '1475269241000', 'y' => '1']
];
foreach($ar AS $key => $val) {
$ar[$key] = array_values(array_map('intval', $val));
}
var_dump($ar);
Related
I have this multidimensional array:
array(3) {
[0]=>
array(2) {
["casestatus"]=> string(4) "Open"
["casestatus_count"]=> int(2)
}
[1]=>
array(2) {
["casestatus"]=> string(7) "Pending"
["casestatus_count"]=> int(1)
}
[2]=>
array(2) {
["casestatus"]=> string(4) "Open"
["casestatus_count"]=> int(1)
}
}
From the array above I am able to merge based on the casestatus key as shown below:
$newArray = array();
foreach($mergedData as $data)
{
if(!isset($newArray[$data["casestatus"]]))
{
$newArray[$data["casestatus"]] = array(
"casestatus" => $data["casestatus"],
"casestatus_count" => 0
);
}
$newArray[$data["casestatus"]]["casestatus_count"] += $data["casestatus_count"];
}
var_dump($newArray);
From which I get:
array(2) {
["Open"]=>
array(2) {
["casestatus"]=> string(4) "Open"
["casestatus_count"]=> int(3)
}
["Pending"]=>
array(2) {
["casestatus"]=> string(7) "Pending"
["casestatus_count"]=> int(1)
}
}
Note how my array keys are my casestatus. So is there a way of not having this and instead have my array keys as:
array(2) {
[0]=>
array(2) {
["casestatus"]=> string(4) "Open"
["casestatus_count"]=> int(3)
}
[1]=>
array(2) {
["casestatus"]=> string(7) "Pending"
["casestatus_count"]=> int(1)
}
}
Just do array_values($newArray) after the process.
var_dump(array_values($newArray));
array_values()
You could create a map of status to counts, then sum them:
<?php
$tickets =
[
[
'status' => 'Open',
'count' => 2
],
[
'status' => 'Closed',
'count' => 1
],
[
'status' => 'Open',
'count' => 1
]
];
foreach($tickets as $ticket)
$status_counts[$ticket['status']][] = $ticket['count'];
foreach($status_counts as $status => $counts)
$result[] = [
'status' => $status,
'count' => array_sum($counts)
];
var_export($result);
Output:
array (
0 =>
array (
'status' => 'Open',
'count' => 3,
),
1 =>
array (
'status' => 'Closed',
'count' => 1,
),
)
However a simpler format may suffice:
$result = array_map('array_sum', $status_counts);
var_export($result);
Output:
array (
'Open' => 3,
'Closed' => 1,
)
I'm trying to parse a json file into a csv, the problem occurs when I encounter a multidimensional array with the parents elements - i need every child of that parent array to be a separate line in the csv with the parents values.
The problem arises when I try looping through child elements and can't access the parents values - I'm thinking about making a concactinated string before looping the data and then printing the string + data foreach values, but this seems like a hack. Does anyone know a better way to solve this?
[0]=>
array(7) {
["platform"]=>
string(7) "web"
["date"]=>
string(10) "2019-04-17"
["name"]=>
string(42) "something.com"
["data"]=>
array(10) {
[0]=>
array(2) {
["revenue"]=>
float(0.02)
["countryCode"]=>
string(2) "AU"
}
[1]=>
array(2) {
["revenue"]=>
float(0.03)
["countryCode"]=>
string(2) "BE"
}
[2]=>
array(2) {
["revenue"]=>
float(0.02)
["countryCode"]=>
string(2) "CH"
}
[3]=>
array(2) {
["revenue"]=>
float(0.01)
["countryCode"]=>
string(2) "CZ"
}
[4]=>
array(2) {
["revenue"]=>
float(0.34)
["countryCode"]=>
string(2) "GB"
}
[5]=>
array(2) {
["revenue"]=>
float(0.03)
["countryCode"]=>
string(2) "NL"
}
[6]=>
array(2) {
["revenue"]=>
float(0.01)
["countryCode"]=>
string(2) "NO"
}
[7]=>
array(2) {
["revenue"]=>
float(0.01)
["countryCode"]=>
string(2) "NZ"
}
[8]=>
array(2) {
["revenue"]=>
float(0.03)
["countryCode"]=>
string(2) "SE"
}
[9]=>
array(2) {
["revenue"]=>
float(2.46)
["countryCode"]=>
string(2) "US"
}
}
}
[1]=>
array(7) {
["platform"]=>
string(7) "web"
["date"]=>
string(10) "2019-04-17"
["name"]=>
string(42) "something-else.com"
["data"]=>
array(10) {
[0]=>
array(2) {
["revenue"]=>
float(0.72)
["countryCode"]=>
string(2) "AU"
}
[1]=>
array(2) {
["revenue"]=>
float(12.03)
["countryCode"]=>
string(2) "BE"
}
[2]=>
array(2) {
["revenue"]=>
float(0.27)
["countryCode"]=>
string(2) "CH"
}
[3]=>
array(2) {
["revenue"]=>
float(8.71)
["countryCode"]=>
string(2) "CZ"
}
}
}
I want it to be converted into :
platform,date,name,revenue,countryCode
"web","2019-04-17","something.com",0.02,"AU"
"web","2019-04-17","something.com",0.03,"BE"
"web","2019-04-17","something.com",0.02,"CH"
"web","2019-04-17","something.com",0.01,"CZ"
"web","2019-04-17","something.com",0.34,"GB"
...
Managed to make this work:
$f = fopen('examlple.csv', 'w');
$firstLineKeys = false;
foreach ($array as $line)
{
if (empty($firstLineKeys))
{
$firstLineKeys = array_keys($line);
array_pop($firstLineKeys); //removing data as we will loop over it later, and adding the 2 data keys that will be in the results.
$firstLineKeys[] = "country";
$firstLineKeys[] = "revenue";
fputcsv($f, $firstLineKeys);
$firstLineKeys = array_flip($firstLineKeys);
}
$line_array = array($line);
$string = array();
foreach ($line as $key => $value)
{
if($key !== "data"){
$string[]= $value;
}else{
foreach($value as $country){
$new_string = $string;
$new_string[]=$country['countryCode'];
$new_string[]=$country['revenue'];
fputcsv($f, $new_string);
}
}
array_push($line_array,$value);
}
}
But i'm wondering if there is a better way to do it.
I have created an array like below please check if it helps you:
$final = array();
$i = 0;
$f = array();
echo '<pre>';
foreach($arr as $ar) {
$final[$i] = array(
'platform' => $ar['platform'],
'date' => $ar['date'],
'name' => $ar['name'],
);
foreach($ar['data'] as $key => $value) {
$f[] = array_merge($final[$i], $value);
}
$i++;
}
print_r($f);
die;
example:
$arr = array(
array(
'platform' => 'web',
'date' => 'web',
'name' => 'web',
'data' => array(
array(
'revenue' => '0.02',
'countryCode' => 'AU',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU',
),
)
),
array(
'platform' => 'web1',
'date' => 'web',
'name' => 'web',
'data' => array(
array(
'revenue' => '0.0211',
'countryCode' => 'AU11',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU12',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU13',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU14',
),
)
),
array(
'platform' => 'web2',
'date' => 'web',
'name' => 'web',
'data' => array(
array(
'revenue' => '0.02',
'countryCode' => 'AU21',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU22',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU23',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU24',
),
)
),
array(
'platform' => 'web3',
'date' => 'web',
'name' => 'web',
'data' => array(
array(
'revenue' => '0.02',
'countryCode' => 'AU31',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU32',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU33',
),
array(
'revenue' => '0.02',
'countryCode' => 'AU34',
),
)
)
);
$final = array();
$i = 0;
$f = array();
echo '<pre>';
foreach($arr as $ar) {
$final[$i] = array(
'platform' => $ar['platform'],
'date' => $ar['date'],
'name' => $ar['name'],
);
foreach($ar['data'] as $key => $value) {
$f[] = array_merge($final[$i], $value);
}
$i++;
}
print_r($f);
die;
I have two arrays like:
$team = [
['id' => 1, 'name' => 'Team A'],
['id' => 2, 'name' => 'Team B'],
['id' => 3, 'name' => 'Team C'],
];
$people = [
['id' => 1, 'name' => 'Mark Hamill', 'team' => 1],
['id' => 2, 'name' => 'Nicolas Cage', 'team' => 2],
['id' => 3, 'name' => 'Tom Cruise', 'team' => 3],
['id' => 4, 'name' => 'Tom Hanks', 'team' => 1],
['id' => 5, 'name' => 'Brad Pitt', 'team' => 2],
['id' => 6, 'name' => 'Paul Smith', 'team' => 3],
['id' => 7, 'name' => 'Matt Daemon', 'team' => 1],
['id' => 8, 'name' => 'Robert Redford', 'team' => 2],
]
I would like to merge the $people array into the $team array as a child node based on the team id. So the result would be:
$team = [
[
'id' => 1,
'name' =>'Team A',
'members' => [
['id' => 1, 'name' => 'Mark Hamill', 'team' => 1],
['id' => 4, 'name' => 'Tom Hanks', 'team' => 1],
['id' => 7, 'name' => 'Matt Daemon', 'team' => 1],
]
],
[
'id' => 2,
'name' =>'Team B',
'members' => [
['id' => 2, 'name' => 'Nicolas Cage', 'team' => 2],
['id' => 5, 'name' => 'Brad Pitt', 'team' => 2],
['id' => 8, 'name' => 'Robert Redford', 'team' => 2],
]
],
[
'id' => 3,
'name' =>'Team C',
'members' => [
['id' => 3, 'name' => 'Tom Cruise', 'team' => 3],
['id' => 6, 'name' => 'Paul Smith', 'team' => 3],
]
],
];
I know I can loop through $team and add the relevant $people one at a time based on their 'team' id, but I was wondering if there was a more efficient way of doing this. In my project, either of the arrays could grow to contain up to around 50 items each and processing these one at a time is really slowing the page down.
Thanks
This will loop your $teams array and intersect with an array_column to get the arrays you want.
$teampeople = array_column($people, "team");
//Creates a lookup array of the teams from people array
foreach($team as &$t){
// Here I match from the lookup array and get the "main" arrays.
// Array_values remove the indexed from the resulting array to make it 0,1,2 etc.
$t['members'] = array_values(array_intersect_key($people, array_intersect($teampeople, [$t['id']])));
}
unset($t); // just to make sure you don't accidentally change the array
var_dump($team);
Outputs:
array(3) {
[0]=>
array(3) {
["id"]=>
int(1)
["name"]=>
string(6) "Team A"
["members"]=>
array(3) {
[0]=>
array(3) {
["id"]=>
int(1)
["name"]=>
string(11) "Mark Hamill"
["team"]=>
int(1)
}
[1]=>
array(3) {
["id"]=>
int(4)
["name"]=>
string(9) "Tom Hanks"
["team"]=>
int(1)
}
[2]=>
array(3) {
["id"]=>
int(7)
["name"]=>
string(11) "Matt Daemon"
["team"]=>
int(1)
}
}
}
[1]=>
array(3) {
["id"]=>
int(2)
["name"]=>
string(6) "Team B"
["members"]=>
array(3) {
[0]=>
array(3) {
["id"]=>
int(2)
["name"]=>
string(12) "Nicolas Cage"
["team"]=>
int(2)
}
[1]=>
array(3) {
["id"]=>
int(5)
["name"]=>
string(9) "Brad Pitt"
["team"]=>
int(2)
}
[2]=>
array(3) {
["id"]=>
int(8)
["name"]=>
string(14) "Robert Redford"
["team"]=>
int(2)
}
}
}
[2]=>
&array(3) {
["id"]=>
int(3)
["name"]=>
string(6) "Team C"
["members"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
int(3)
["name"]=>
string(10) "Tom Cruise"
["team"]=>
int(3)
}
[1]=>
array(3) {
["id"]=>
int(6)
["name"]=>
string(10) "Paul Smith"
["team"]=>
int(3)
}
}
}
}
https://3v4l.org/kmvuR
try this:
foreach ($team as $t) {
$t['members'] = array_filter($people, function ($var) use ($t) {
return ($var['team'] == $t['id']);
})
}
I have an array as below:
$people = array(
200 => array(
'id' => 12345,
'first_name' => 'Joe',
'surname' => 'Bloggs',
'age' => 23,
'sex' => 'm'
),
100 => array(
'id' => 12346,
'first_name' => 'Adam',
'surname' => 'Smith',
'age' => 18,
'sex' => 'm'
),
500 => array(
'id' => 12347,
'first_name' => 'Amy',
'surname' => 'Jones',
'age' => 21,
'sex' => 'f'
)
I want to sort this array on the first value that you can see as 200, 100 and 500.
$result = array(
array('name' => 'Tahir', 'age' => '40'),
array('name' => 'Usman', 'age' => '30'),
array('name' => 'Danish', 'age' => '20'),
array('name' => 'Aneeq', 'age' => '10')
);
echo '<pre>';
print_r($result);
echo '</pre>';
foreach ($result as $key => $row) {
$name[$key] = $row['name'];
$age[$key] = $row['age'];
}
array_multisort($age, SORT_ASC, $result);
echo '<pre>';
print_r($result);
echo '</pre>';
echo "<pre>";
echo "Name\t\tAge";
foreach ( $result as $var ) {
echo "\n", $var['name'], "\t\t", $var['age'];
}
You can use ksort() use ascending order and krsort() for descending order.
ksort($people);
krsort($people);
This should be as simple as:
ksort($people);
To make it sort by the actual numeric value (to make 1000 come after 500 not after 100), use:
ksort($people, SORT_NUMERIC);
ksort() sorts an array by its keys.
For example:
php > var_dump($people);
array(3) {
[200]=>
array(5) {
["id"]=>
int(12345)
["first_name"]=>
string(3) "Joe"
["surname"]=>
string(6) "Bloggs"
["age"]=>
int(23)
["sex"]=>
string(1) "m"
}
[100]=>
array(5) {
["id"]=>
int(12346)
["first_name"]=>
string(4) "Adam"
["surname"]=>
string(5) "Smith"
["age"]=>
int(18)
["sex"]=>
string(1) "m"
}
[500]=>
array(5) {
["id"]=>
int(12347)
["first_name"]=>
string(3) "Amy"
["surname"]=>
string(5) "Jones"
["age"]=>
int(21)
["sex"]=>
string(1) "f"
}
}
php > ksort($people);
php > var_dump($people);
array(3) {
[100]=>
array(5) {
["id"]=>
int(12346)
["first_name"]=>
string(4) "Adam"
["surname"]=>
string(5) "Smith"
["age"]=>
int(18)
["sex"]=>
string(1) "m"
}
[200]=>
array(5) {
["id"]=>
int(12345)
["first_name"]=>
string(3) "Joe"
["surname"]=>
string(6) "Bloggs"
["age"]=>
int(23)
["sex"]=>
string(1) "m"
}
[500]=>
array(5) {
["id"]=>
int(12347)
["first_name"]=>
string(3) "Amy"
["surname"]=>
string(5) "Jones"
["age"]=>
int(21)
["sex"]=>
string(1) "f"
}
}
php >
You can try this solution.
<?php
$people = array(
200 => array(
'id' => 12345,
'first_name' => 'Joe',
'surname' => 'Bloggs',
'age' => 23,
'sex' => 'm'
),
100 => array(
'id' => 12346,
'first_name' => 'Adam',
'surname' => 'Smith',
'age' => 18,
'sex' => 'm'
),
500 => array(
'id' => 12347,
'first_name' => 'Amy',
'surname' => 'Jones',
'age' => 21,
'sex' => 'f'
));
ksort($people, SORT_NUMERIC);
print_r($people);
?>
You can use the following two functions according to your requirement:-
ksort() - sort associative arrays in ascending order, according to the key
krsort() - sort associative arrays in descending order, according to the key
How you can use it:-
ksort($people);
krsort($people);
Let's say I have an array and I want to search for a value should return multiple results:
array(2) {
[0] => array(2) {
["id"] => string(2) "1"
["custom"] => string(1) "2"
}
[1] => array(2) {
["id"] => string(2) "2"
["custom"] => string(1) "5"
}
[2] => array(2) {
["id"] => string(2) "3"
["custom"] => string(1) "2"
}
}
I want to search for key custom with value = 2, with the following result:
array(2) {
[0] => array(2) {
["id"] => string(2) "1"
["custom"] => string(1) "2"
}
[1] => array(2) {
["id"] => string(2) "3"
["custom"] => string(1) "2"
}
}
Is this possible without looping through array? Is there such class or built in function for this?
You could use:
array_values( array_filter($array, function($item) { return $item['custom'] == 2; }) );
array_values($array) is used to return an array with indexes which is consecutive, i.e. from 0, 1, 2, ... upward.
the array_filter function is probably what you want.
$array = [
[
'id' => '1',
'custom' => '2'
],
[
'id' => '2',
'custom' => '5'
],
[
'id' => '3',
'custom' => '2'
]
];
$customs = array_filter(
$array,
function ($arr) {
return is_array($arr) && array_key_exists('custom', $arr) && $arr['custom'] === '2';
}
);
You could simply remove the values you don't want by un-setting them from the array:
foreach($array as $key => $item) {
if($item['custom'] !== 2) {
unset($array[$key]);
}
}
Example
This is an alternative to array_values(), but essentially does it the same way.