I am trying to group an array by sport. It could be n number of sports. Finally, then create a new array with it. Is there an efficient way to this without going overkill?
$sports = [
['sport' => 'soccer', 'id' => 97487];
['sport' => 'soccer', 'id' => 244800];
['sport' => 'soccer', 'id' => 258740];
['sport' => 'basketball', 'id' => 147884];
['sport' => 'baseball', 'id' => 222240];
['sport' => 'baseball', 'id' => 222245];
];
Initial array:
array(6) {
[0]=>
array(2) {
["sport"]=>
string(6) "soccer"
["id"]=>
int(97487)
}
[1]=>
array(2) {
["sport"]=>
string(6) "soccer"
["id"]=>
int(244800)
}
[2]=>
array(2) {
["sport"]=>
string(6) "soccer"
["id"]=>
int(258740)
}
[3]=>
array(2) {
["sport"]=>
string(10) "basketball"
["id"]=>
int(147884)
}
[4]=>
array(2) {
["sport"]=>
string(8) "baseball"
["id"]=>
int(222240)
}
[5]=>
array(2) {
["sport"]=>
string(8) "baseball"
["id"]=>
int(222245)
}
}
Desired results:
array(3)
{
[0]=>
array(3) {
[0]=>
array(2) {
["sport"]=>
string(6) "soccer"
["id"]=>
int(97487)
}
[1]=>
array(2) {
["sport"]=>
string(6) "soccer"
["id"]=>
int(244800)
}
[2]=>
array(2) {
["sport"]=>
string(6) "soccer"
["id"]=>
int(258740)
}
}
[1]=>
array(1) {
[0]=>
array(2) {
["sport"]=>
string(10) "basketball"
["id"]=>
int(147884)
}
}
[2]=>
array(2) {
[0]=>
array(2) {
["sport"]=>
string(8) "baseball"
["id"]=>
int(222240)
}
[1]=>
array(2) {
["sport"]=>
string(8) "baseball"
["id"]=>
int(222245)
}
}
}
You can group the array like so:
$sports = [
['sport' => 'soccer', 'id' => 97487],
['sport' => 'soccer', 'id' => 244800],
['sport' => 'soccer', 'id' => 258740],
['sport' => 'basketball', 'id' => 147884],
['sport' => 'baseball', 'id' => 222240],
['sport' => 'baseball', 'id' => 222245]
];
// we will build an array here where the key is the sport
// name and the value is an array of objects pertaining
// to that sport i.e. 'basketball' => [bb1, bb2, ...]
$array = array();
// now consider every sport object in your original array
foreach($sports as $key => $item)
{
if (array_key_exists($item['sport'], $array)) {
// we encountered this same sport in the past so we
// know $array['sportName'] already exists and can
// push right to it
$array[$item['sport']][] = $item;
} else {
// we have never seen this sport before and now must
// insert the sport into $array['sportName'] = []
// and push this sport object to it
$array[$item['sport']] = [$item];
}
}
// since $array's keys are the names of the sports themselves, but
// you want the keys to be numeric, this will build a new array
// from just the values of $array which at this point contains
// grouped arrays of sport objects
$result = array_values($array);
// print the results for good measure :)
print_r($result);
This works by looping over your sports array and building a second array of [sportName => arrayOfThatSport]. Inside the for loop, we are checking to see if a given sport already exists in this array. If it does, great, add the sport to the corresponding array for that sport. Otherwise, create a new array for that sport available at $array['sportName'] = [sportObject]. If you consider several iterations of the loop you will see that we're either always adding to an existing $array['sportName'] array, or creating a new array at this position whenever we encounter a new sport we've never seen before. This gives us a final array similar to: [ "sport
: [...], "sport2": [...] ] but in your case you want a numeric array not an associative array, hence the call to array_values.
This is my suggested solution.
$groupedSports = [];
foreach ($sports as $item) {
if (empty($groupedSports[$item['sport']])) {
$groupedSports[$item['sport']] = [];
}
$groupedSports[$item['sport']][] = $item;
}
Short explanation:
line 1: we initialize an empty array
line 2: we start a loop on the original array
line 3-5: if it's the first occurrence for the current sport, we initialize an empty array for that sport (avoid warnings)
line 6: we assign current item to the appropriate array
Related
I want to merge two different array data in one array, but i'm confuse how to use array_push in this case.
this is example of my data input:
["author"]=>
array(2) {
[0]=>
string(1) "John"
[1]=>
string(1) "Doe"
}
["title"]=>
array(2) {
[0]=>
string(1) "book a"
[1]=>
string(1) "book b"
}
And the result in one array that i mean, like this:
["books"]=>
array(2) {
[0] =>
array(2) {
["author"]=>
string(1) "John"
["title"]=>
string(1) "book a"
}
[1] =>
array(2) {
["author"]=>
string(1) "Doe"
["title"]=>
string(1) "book b"
}
}
I already try using this way but it just return 1 from each array:
$data['books'] = [];
array_push($data['books'], [
'author' => $data['author'],
'title' => $data['title']
]);
if (isset($data['books'])) {
foreach ($data['books'] as $k => $v) {
$data['books'][$k]['author'] = (int)$v['author'];
$data['books'][$k]['title'] = (int)$v['title'];
}
}
result:
["books"]=>
array(1) {
[0]=>
array(2) {
["author"]=>
int(1)
["title"]=>
int(1)
}
}
You have to transpose your arrays with the keys in mind.
function transpose(array $arr){
$transArr = [];
foreach($arr as $keyRow => $subArr) {
foreach($subArr as $keyCol => $value) {
$transArr[$keyCol][$keyRow] = $value;
}
}
return $transArr;
}
This function can be used universally for similar problems. The function comes from this class.
How to use:
$input = [
"author"=> ["John","Doe"],
"title" => ["book a","book b"],
];
$books = transpose($input);
echo '<pre>';
var_export($books);
Or if you want to use the class:
$books = tableArray::create($input)
->transpose()
->fetchAll()
;
Output:
array (
0 =>
array (
'author' => 'John',
'title' => 'book a',
),
1 =>
array (
'author' => 'Doe',
'title' => 'book b',
),
)
If "author" and "title" exist as two arrays, $ input must first be created like this:
$input = ['author' => $arrayAuthor, 'title' => $arrayTitle];
I have following array.
array(5) {
[0]=>
array(1) {
["Cars"]=>
string(5) "Volvo"
}
[1]=>
array(1) {
["Cars"]=>
string(4) "Fiat"
}
[2]=>
array(1) {
["Cars"]=>
string(5) "Volvo"
}
[3]=>
array(1) {
["Cars"]=>
string(8) "Mercedes"
}
[4]=>
array(1) {
["Cars"]=>
string(5) "Volvo"
}
I need to count all Duplicates and create a new array where i have the name of each group and the number how many duplicates there are. Could someone help me with a simple solution?
Find all values of Carswith array_column(), and count their values with array_count_values().
$array = array(
['Cars' => 'Volvo'],
['Cars' => 'Fiat'],
['Cars' => 'Volvo'],
['Cars' => 'Mercedes'],
['Cars' => 'Volvo'],
);
print_r(array_count_values(array_column($array, "Cars")));
Outputs
Array (
[Volvo] => 3
[Fiat] => 1
[Mercedes] => 1
)
Live demo at https://3v4l.org/1jhmh
I have an array with 4 data each, what i want to accomplish is to remove
value of duplicate/equal tag_id and put/append the tag_images together
of the same tag_id. I also used array_unique but i don't know where to put it.
My array has a tag_id,tag_slug,tag_color, and tag_images(array). The last 2 array have the same data except with tag_images, I want to merge those data as one and put the tag_images in an array.
example:
array(4) {
[0]=>
array(4) {
["tag_id"]=> int(25)
["tag_slug"]=> string(5) "green"
["tag_color"]=> string(7) "#81d742"
["tag_images"]=> array(1) {
[0]=> string(75) "http://localhost/mysite/wp-content/uploads/2018/08/long-sleeve-tee.jpg"
}
}
[1]=>
array(4) {
["tag_id"]=> int(23)
["tag_slug"]=> string(3) "red"
["tag_color"]=> string(7) "#dd3333"
["tag_images"]=> array(1) {
[0]=> string(69) "http://localhost/mysite/wp-content/uploads/2018/08/vneck-tee.jpg"
}
}
[2]=>
array(4) {
["tag_id"]=> int(23)
["tag_slug"]=> string(3) "red"
["tag_color"]=> string(7) "#dd3333"
["tag_images"]=> array(1) {
[0]=> string(66) "http://localhost/mysite/wp-content/uploads/2018/08/beanie.jpg"
}
}
}
Output:
array(4) {
[0]=>
array(4) {
["tag_id"]=>
int(25)
["tag_slug"]=>
string(5) "green"
["tag_color"]=>
string(7) "#81d742"
["tag_images"]=>
array(1) {
[0]=>
string(75) "http://localhost/mysite/wp-content/uploads/2018/08/long-sleeve-tee.jpg"
}
}
[1]=>
array(4) {
["tag_id"]=>
int(23)
["tag_slug"]=>
string(3) "red"
["tag_color"]=>
string(7) "#dd3333"
["tag_images"]=>
array(1) {
[0]=>
string(66) "http://localhost/mysite/wp-content/uploads/2018/08/beanie.jpg"
[1]=>
string(69) "http://localhost/mysite/wp-content/uploads/2018/08/vneck-tee.jpg"
}
}
}
You can use array_merge_recursive()
Or use this function from this answer
function my_array_merge(&$array1, &$array2) {
$result = Array();
foreach($array1 as $key => &$value) {
$result[$key] = array_merge($value, $array2[$key]);
}
return $result;
}
$array = my_array_merge($array1, array2);
print_r($array);
I'd iterate the main array and build a second one.
$mainArray = array
(
array("tag_id" => 25,
"tag_slug" => "green",
"tag_color" => "#81d742",
"tag_images" => array("http://localhost/mysite/wp-content/uploads/2018/08/long-sleeve-tee.jpg")
),
array("tag_id" => 23,
"tag_slug" => "red",
"tag_color" => "#dd3333",
"tag_images" => array("http://localhost/mysite/wp-content/uploads/2018/08/vneck-tee.jpg")
),
array("tag_id" => 23,
"tag_slug" => "red",
"tag_color" => "#dd3333",
"tag_images" => array("http://localhost/mysite/wp-content/uploads/2018/08/beanie.jpg")
)
);
$freshArray = array();
foreach ($mainArray as $value)
{
$key = array_search($value['tag_id'], array_column($freshArray, 'tag_id'));
if (false === $key)
$freshArray[] = $value;
else
$freshArray[$key]['tag_images'][] = $value['tag_images'][0];
}
var_dump($freshArray);
Output :
array (size=2)
0 =>
array (size=4)
'tag_id' => int 25
'tag_slug' => string 'green' (length=5)
'tag_color' => string '#81d742' (length=7)
'tag_images' =>
array (size=1)
0 => string 'http://localhost/mysite/wp-content/uploads/2018/08/long-sleeve-tee.jpg' (length=70)
1 =>
array (size=4)
'tag_id' => int 23
'tag_slug' => string 'red' (length=3)
'tag_color' => string '#dd3333' (length=7)
'tag_images' =>
array (size=2)
0 => string 'http://localhost/mysite/wp-content/uploads/2018/08/vneck-tee.jpg' (length=64)
1 => string 'http://localhost/mysite/wp-content/uploads/2018/08/beanie.jpg' (length=61)
Data is coming from 2 differents SQL request, so i have 2 arrays like :
FIRST ARRAY
array(6) {
[0]=>
array(2) {
["edible"]=>
string(3) "600"
["Food"]=>
string(4) "Fruit"
}
[1]=>
array(2) {
["edible"]=>
string(3) "500"
["Food"]=>
string(6) "Vegetables"
}
[2]=>
array(2) {
["edible"]=>
string(4) "1000"
["Food"]=>
string(3) "meat"
}
...
SECOND ARRAY
array(5) {
[0]=>
array(2) {
["out-of-date"]=>
string(3) "17"
["Food"]=>
string(4) "Fruit"
}
[1]=>
array(2) {
["out-of-date"]=>
string(3) "54"
["Food"]=>
string(3) "Vegetables"
}
[2]=>
array(2) {
["out-of-date"]=>
string(2) "60"
["Food"]=>
string(3) "meat"
}
...
What i would like is to merge the two arrays, but not with a function like array_merge or array_merge_recursive.
Because i would like to just add a row (key + value) like
["out-of-date"]=>
string(3) "17""
in the first array if we have the same Food (key)
output result desired :
array(6) {
[0]=>
array(3) {
["out-of-date"]=>
string(3) "17"
["edible"]=>
string(3) "600"
["Food"]=>
string(4) "Fruit"
}
...
You need to make a loop inside loop and verify the food key, if is equal merge the values to another array, Try this code:
<?php
$array1 = array();
$array1[] = array('food' => 'Fruit', 'edible' => '600');
$array1[] = array('food' => 'Vegetables', 'edible' => '500');
$array1[] = array('food' => 'meat', 'edible' => '700');
$array2 = array();
$array2[] = array('food' => 'Fruit', 'out-of-date' => '17');
$array2[] = array('food' => 'Vegetables', 'out-of-date' => '15');
$array_merged = array();
foreach ($array1 as $key => $value) {
$array_merged[$key] = $value;
foreach ($array2 as $ke => $val) {
if ($val['food'] == $value['food']) {
$array_merged[$key]['out-of-date'] = $val['out-of-date'];
}
}
}
print_r($array_merged);
I'm not sure about structure of your database table. But let's you have two tables in your MySql database:
First - edible | Food
Second - out_of_date | Food
So you can query your array by using join mysql operation. You need sql like below:
SELECT *
FROM First
LEFT JOIN Second ON First.Food=Second.Food
Also, you can use additional conditions for all tables like:
SELECT *
FROM First
LEFT JOIN Second ON First.Food=Second.Food
WHERE First.edible = 1000 AND Second.out_of_date = 10
You can find more information here: http://dev.mysql.com/doc/refman/5.7/en/join.html
After fetching a result from the database, and preparing the array for the JSON enconde, I face a dilemma on how to reference the array 'data' inside the main array.
The "[0]" by far is an error of my logic...
while ($row =$result->fetch()) {
$name = $row['country'];
$id = $row['id']
$username = $row['username'];
$subtotal = $row['subtotal'];
if ( /* If $id exist in array row['series']}*/ ) {
///?????/////
/// Add array to 'DATA'
////?????////
$rows['series']["$id"]["$name"]['data'][]=array("$username", $subtotal);
}
else {
$rows['series'][]= array('id' => "$id", 'name' => "$name", 'data' => array("$username", $subtotal));
}
The vardump show as follow:
array(1) {
["series"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
string(7) "hn"
["name"]=>
string(8) "HN"
["data"]=>
array(2) {
[0]=>
string(17) "GK_5"
[1]=>
string(5) "86040"
}
}
[1]=>
array(3) {
["id"]=>
string(7) "hn"
["name"]=>
string(8) "HN"
["data"]=>
array(2) {
[0]=>
string(17) "GK_8"
[1]=>
string(5) "20358"
}
}
}
}
But I want to add the last item with same id/name like this:
array(1) {
["series"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
string(7) "hn"
["name"]=>
string(8) "HN"
["data"]=>
array(2) {
[0]=>
string(17) "GK_5"
[1]=>
string(5) "86040"
}
array(2) {
[0]=>
string(17) "GK_8"
[1]=>
string(5) "20358"
}
}
}
}
The most natural way would be to change your data structure a bit, so that the series array is indexed by the row ID instead of an arbitrary running index. The would allow you to rewrite your loop to (using mysqli syntax as an example):
$stmt->bind_result($id, $country, $username, $subtotal);
$series = array();
while ( $stmt->fetch() ) {
$series[$id]['country'] = $country;
$series[$id]['data'][] = array(
'username' => $username,
'subtotal' => $subtotal,
);
}
which will give you a data structure like:
$series = array(
'hn' => array(
'country' => 'HN',
'data' => array(
0 => array(
'username' => 'GK_5',
'subtotal' => 86040
),
1 => array(
'username' => 'GK_8',
'subtotal' => 20358
),
// ...
)
),
// ...
);
If you need the data in the exact format shown in your post, you can of course loop over this array with foreach to transform it, e.g.:
$rows = array();
foreach ( $series as $id => $record ) {
$record['id'] = $id;
$rows['series'][] = $record;
}