PHP array duplicate add value to that index - php

am just trying to fix my problem. Exactly: I have array that has been filled up by database (music playlist). That array contains duplicates what am trying to achieve is (example rows from database):
-- ID: 0 | ARTIST: SOMETHING1 | TITLE: SOMETHING1 | TIME: 04:00 | REPEAT: 1 |
-- ID: 1 | ARTIST: SOMETHING2 | TITLE: SOMETHING2 | TIME: 02:40 | REPEAT: 1 |
-- ID: 2 | ARTIST: SOMETHING3 | TITLE: SOMETHING3 | TIME: 03:20 | REPEAT: 1 |
-- ID: 3 | ARTIST: SOMETHING1 | TITLE: SOMETHING1 | TIME: 04:00 | REPEAT: 1 |
-- ID: 4 | ARTIST: SOMETHING1 | TITLE: SOMETHING1 | TIME: 04:00 | REPEAT: 1 |
-- ID: 5 | ARTIST: SOMETHING1 | TITLE: SOMETHING1 | TIME: 04:00 | REPEAT: 1 |
-- ID: 6 | ARTIST: SOMETHING1 | TITLE: SOMETHING1 | TIME: 04:00 | REPEAT: 1 |
So those values would be in array now how would I check for those duplicates in that array. If there would be duplicate I'd want to remove that duplicate but leave only one and add +1 to repeat for each duplicate. Example from above rows:
-- ID: 0 | ARTIST: SOMETHING1 | TITLE: SOMETHING1 | TIME: 04:00 | REPEAT: 5 |
-- ID: 1 | ARTIST: SOMETHING2 | TITLE: SOMETHING2 | TIME: 02:40 | REPEAT: 1 |
-- ID: 2 | ARTIST: SOMETHING3 | TITLE: SOMETHING3 | TIME: 03:20 | REPEAT: 1 |
Am sorry if there is already post but couldn't find way to explain it better.

You can use this function. Kindly make sure you change the ARTIST key to meet your need.
function remove_duplicates($playlist){
$filtered = [];
foreach($playlist as $music){
$array_exist = array_filter($filtered, function($val) use ($music) {
return ($val['ARTIST'] === $music['ARTIST']) &&
($val['TITLE'] === $music['TITLE']);
});
if( empty($array_exist) ){
$filtered[] = $music;
}else{
foreach($array_exist as $index => $arr){
$filtered[$index]['REPEAT'] += 1;
}
}
}
return $filtered;
}
Example
$music_playlist = [
['ID' => 1, 'ARTIST' => 'SOMETHING1', 'TITLE' => 'SOMETHING1', 'TIME' => '04:00', 'REPEAT' => 1],
['ID' => 2, 'ARTIST' => 'SOMETHING2', 'TITLE' => 'SOMETHING2', 'TIME' => '02:40', 'REPEAT' => 1],
['ID' => 3, 'ARTIST' => 'SOMETHING3', 'TITLE' => 'SOMETHING3', 'TIME' => '03:20', 'REPEAT' => 1],
['ID' => 4, 'ARTIST' => 'SOMETHING1', 'TITLE' => 'SOMETHING1', 'TIME' => '04:00', 'REPEAT' => 1],
['ID' => 5, 'ARTIST' => 'SOMETHING1', 'TITLE' => 'SOMETHING1', 'TIME' => '04:00', 'REPEAT' => 1],
['ID' => 6, 'ARTIST' => 'SOMETHING1', 'TITLE' => 'SOMETHING1', 'TIME' => '04:00', 'REPEAT' => 1],
['ID' => 7, 'ARTIST' => 'SOMETHING1', 'TITLE' => 'SOMETHING1', 'TIME' => '04:00', 'REPEAT' => 1]
];
print_r(remove_duplicates($music_playlist));

You can use a for/foreach loop with every data you have. Then add the new data when something is not there. And put an auto increment on the ID with primary key.

If it has to be in PHP and not SQL, then how about:
$keys=[];
foreach($rows as $row) {
$id=$row['ARTIST'].$row['TITLE'];
if ( !isset($keys[$id]) ) $keys[$id]=$row;
else {
$rowX=$keys[$id];
$rowX['REPEAT']++;
$keys[$id]=$rowX;
}
}
See http://sandbox.onlinephpfunctions.com/code/8558cf3ae956ac358962bf3c83ecabc299a38af3 for a working example

Related

Multi Dimensional Array Construct

I have this type of array that I got from my SQL result.
+-------------+---------------+-----------------+----------------+
| business_id | business_name | business_branch | branch_contact |
+-------------+---------------+-----------------+----------------+
| 1 | ABC | 1 | 1111111111 |
+-------------+---------------+-----------------+----------------+
| 1 | ABC | 2 | 2222222222 |
+-------------+---------------+-----------------+----------------+
| 1 | ABC | 3 | 3333333333 |
+-------------+---------------+-----------------+----------------+
| 1 | ABC | 4 | 4444444444 |
+-------------+---------------+-----------------+----------------+
| 2 | XYZ | 1 | 5555555555 |
+-------------+---------------+-----------------+----------------+
| 2 | XYZ | 2 | 6666666666 |
+-------------+---------------+-----------------+----------------+
At the beginning I thought of doing a separate database query for each branches and businesses. But got to know it was a bad practice.
I want to construct the results as following
[
{
business_id : 1,
business_name : ABC,
branches : [
{
branch_id : 1,
branch_contact : 1111111111
},
{
branch_id : 2,
branch_contact : 2222222222
},
...
},
{
business_id : 1,
business_name : ABC,
branches : [
{
...
}
}
]
}
The current function I'm trying to build doesn't give the necessary output. It is shown below.
$previousBusiness = '';
$previousBranch = '';
$businessAndBranchArray = [];
$businessArray = [];
$branchArray = [];
foreach ($results as $result) {
$currentBranch = [];
$currentBusiness = [];
$currentMerchant = [];
if($result['business_id'] != $previousBusiness && $result['branch_id'] != $previousBranch){
if($previousBranch != '' && $previousBusiness != ''){
$businessArray['business_id'] = $result['business_id'];
$businessArray['business_id'] = $result['business_name'];
$branchArray['branch_id'] = $result['branch_id'];
$branchArray['branch_contact'] = $result['branch_contact'];
} else {
$businessArray['business_id'] = $result['business_id'];
$businessArray['business_id'] = $result['business_name'];
$branchArray['branch_id'] = $result['branch_id'];
$branchArray['branch_contact'] = $result['branch_contact'];
}
$previousBusiness = $result['business_id'];
} else {
$branchArray['branch_id'] = $result['branch_id'];
$branchArray['branch_contact'] = $result['branch_contact'];
}
}
No need to keep track of previous items and such, just use the ID as an array key so you can check it exists. If you don't want it in your final output, use array_values() to remove the keys:
<?php
$results = [
["business_id" => 1, "business_name" => "ABC", "business_branch" => 1, "branch_contact" => "1111111111"],
["business_id" => 1, "business_name" => "ABC", "business_branch" => 2, "branch_contact" => "2222222222"],
["business_id" => 1, "business_name" => "ABC", "business_branch" => 3, "branch_contact" => "3333333333"],
["business_id" => 1, "business_name" => "ABC", "business_branch" => 4, "branch_contact" => "4444444444"],
["business_id" => 2, "business_name" => "XYZ", "business_branch" => 1, "branch_contact" => "5555555555"],
["business_id" => 2, "business_name" => "XYZ", "business_branch" => 2, "branch_contact" => "6666666666"],
];
$output = [];
foreach ($results as $result) {
if (empty($output[$result["business_id"]])) {
$output[$result["business_id"]] = [
"business_id" => $result["business_id"],
"business_name" => $result["business_name"],
"branches" => [],
];
}
$output[$result["business_id"]]["branches"][] = [
"branch_id" => $result["business_branch"],
"branch_contact" => $result["branch_contact"],
];
}
echo json_encode(array_values($output), true);
Output:
[{"business_id":1,"business_name":"ABC","branches":[{"branch_id":1,"branch_contact":"1111111111"},{"branch_id":2,"branch_contact":"2222222222"},{"branch_id":3,"branch_contact":"3333333333"},{"branch_id":4,"branch_contact":"4444444444"}]},{"business_id":2,"business_name":"XYZ","branches":[{"branch_id":1,"branch_contact":"5555555555"},{"branch_id":2,"branch_contact":"6666666666"}]}]

Laravel Eloquent Nested Group by its Relation

Please help me how to add another nested group by based on game category relation. I have 3 tables related using laravel 5.4 eloquent.
Game Providers Table
+----+-------------+--------------+------------------+
| id | game_name | game_type_id | game_category_id |
+----+-------------+--------------+------------------+
| 1 | Sample | 1 | 1 |
| 1 | Sample 0 | 1 | 2 |
| 2 | Sample 1 | 2 | 1 |
| 3 | Sample 2 | 2 | 2 |
+----+-------------+--------------+------------------+
Game Types
+----+-------------+
| id | name |
+----+-------------+
| 1 | Chess |
| 2 | Poker |
+----+-------------+
Game Categories
+----+-------------+
| id | name |
+----+-------------+
| 1 | Recommended |
| 2 | Optional |
+----+-------------+
I'm done of for first nested for game type relation but i dont know how to add another group by for game categories
$game_providers = GameProvider::all();
$game_providers = $game_providers->groupBy(function ($game_provider) {
return $game_provider->game_type->name;
})->all();
and its output
Array{
'Chess' => Array{
0 => Array{
'id' => 1,
'game_name' => 'Sample',
'game_type_id' => 1,
'game_category_id' => 2
},
1 => Array{
'id' => 2,
'game_name' => 'Sample 0',
'game_type_id' => 1,
'game_category_id' => 2
},
},
'Poker' => Array{
0 => Array{
'id' => 3,
'game_name' => 'Sample 1',
'game_type_id' => 2,
'game_category_id' => 1
},
1 => Array{
'id' => 4,
'game_name' => 'Sample 2',
'game_type_id' => 2,
'game_category_id' => 2
},
},
}
My expected output
Array{
'Chess' => Array{
'Recommended' => Array{
0 => Array{
'id' => 1,
'game_name' => 'Sample',
'game_type_id' => 1,
'game_category_id' => 2
}
},
'Optional' => Array{
0 => Array{
'id' => 2,
'game_name' => 'Sample 0',
'game_type_id' => 1,
'game_category_id' => 2
}
}
},
'Poker' => Array{
'Recommended' => Array{
0 => Array{
'id' => 3,
'game_name' => 'Sample 1',
'game_type_id' => 2,
'game_category_id' => 1
}
},
'Optional' => Array{
0 => Array{
'id' => 4,
'game_name' => 'Sample 2',
'game_type_id' => 2,
'game_category_id' => 2
}
}
}
}
With L5, one way of acieving this can be:
GameProvider::with('game_categories.game_types')
->get()
->groupBy([
'gameTypes.name',
'gameCategories.name'
]);
Should be something along the lines of :
GameProvider::with('game_categories.game_types')->get()->map(function ($game) {
return $game->game_categories->groupBy('name')->map(function ($catGame) {
return $catGame->map(function ($category) {
return $category->game_types->groupBy('name');
});
});
});

Built a multidimensional array with PHP from an SQL query

Form a SQL query i receive the following datas from two differences tables.
|----------------|----------|--------------|
|CON_ContinentId | FRU_Name | FRU_Quantity |
|----------------|----------|--------------|
| 1 | Apple | 100 |
| 1 | Banana | 200 |
| 2 | Peach | 300 |
| 2 | Cherry | 400 |
| 3 | Coconut | 500 |
| 4 | Grape | 1100 |
| 5 | Pear | 1500 |
|----------------|----------|--------------|
I need to get an array like this:
$datas = [
1 => [
[
'FRU_Name' => 'Apple',
'FRU_Quantity' => '100'
],
[
'FRU_Name' => 'Banana',
'FRU_Quantity' => '200'
]
],
2 => [
[
'FRU_Name' => 'Peach',
'FRU_Quantity' => '300'
],
[
'FRU_Name' => 'Cherry',
'FRU_Quantity' => '400'
]
],
3 => [
[
'FRU_Name' => 'Coconut',
'FRU_Quantity' => '500'
]
],
4 => [
[
'FRU_Name' => 'Grape',
'FRU_Quantity' => '1000'
]
],
5 => [
[
'FRU_Name' => 'Pear',
'FRU_Quantity' => '1100'
]
],
]
So, basically, I need to groupe the rows with the same CON_ContinentId and list the FRU_Name and FRU_Quantity.
What I try:
$datas = [];
while ($fetch = $query->fetch(PDO::FETCH_ASSOC)){
$CON_ContinentId = $fetch['CON_ContinentId'];
$FRU_Name = $fetch['FRU_Name'];
$FRU_Quantity = $fetch['FRU_Quantity'];
if (!in_array($CON_ContinentId, $datas)) {
$datas = array(
'CON_ContinentId' => $CON_ContinentId,
'FRU_Name' => $FRU_Name,
'FRU_Quantity' => $FRU_Quantity
);
}
}
But it doesn't work.
Could you please help me ?
Thanks.
There are a few different problems in your code:
Your desired array structure isn't valid, so it's unclear what you want.
$datas isn't initialized. Use $datas = [] instead.
$FRU_Name is being set twice? Did you mean $FRU_Quantity?
This code won't group multiple fruits under their continent ID--it'll put them into an associative array alongside their continent ID.
Every iteration of your results set, just use the CON_ContinentID value as the key, then [] to auto-index the subarrays.
There is no need to declare resultset values to new variables, just apply them to the $datas declaration and move on.
while ($fetch = $query->fetch(PDO::FETCH_ASSOC)){
$datas[$fetch['CON_ContinentId']][]=['FRU_Name'=>$fetch['FRU_Name'],'FRU_Quantity' =>$fetch['FRU_Quantity']];
}
a bit more explanation...
// hard-coded keys -vvvvvvvv-----------------------vvvvvvvvvvvv
$datas[$fetch['CON_ContinentId']][]=['FRU_Name'=>$fetch['FRU_Name'],'FRU_Quantity' =>$fetch['FRU_Quantity']];
// id-^^^^^^^^^^^^^^^^^^^^^^^^^ ^^-auto-index ^^^^^^^^^^^^^^^^^^------------------^^^^^^^^^^^^^^^^^^^^^^-resultset data
// ^^^^^^^^^^-keys start from zero, and increment by one at each new pushed subarray)

Echoing data vertical and horizontal from joined table mySql in PHP

I need your help. Maybe it's all about logical. So my case is:
I have mySql tables, they are:
record table
_______________________________________
Student ID | Question ID | Answer
_______________________________________
1 | 1 | A
2 | 1 | C
3 | 1 | E
1 | 2 | D
2 | 2 | B
3 | 2 | A
....... | .......... | ........
_______________________________________
and student table:
_________________________________
Student ID | Student Name
_________________________________
1 | Ronaldo
2 | Messi
3 | Neymar
.......... | .............
_________________________________
And I want to echoing them in my report page with table like this:
_________________________________________________
Student | Question and Answer
|____________________________________
| 1 | 2 | 3 | ... | ... | ... | ... |
_________________________________________________
Ronaldo | A | D | ...........................
Messi | C | B | ...........................
Neymar | E | A | ...........................
........ | ...................................
_________________________________________________
I use PHP so I repeat with foreach(){} function. But how to echoing data vertically and horizontally in once query?
Sorry for my bad php knowledge and logical. Thanks for your attention.
A simple way to do it (but by no means the only one) :
First fetch your users along with their answers :
SELECT
s.id AS student_id,
s.name AS student_name,
q.question_id,
q.answer
FROM
students AS s
INNER JOIN
questions AS q
ON
s.id = q.student_id;
You should get rows like that :
array(
'student_id' => '1',
'student_name' => 'Ronaldo',
'question_id' => 1,
'answer' => 'A',
)
OR
array(
'student_id' => '2',
'student_name' => 'Messi',
'question_id' => 1,
'answer' => 'C',
),
You could then loop through them to reorganize them :
$data = array();
foreach($rows as $row){
if(!isset($data[$row['student_id']])){
$data[$row['student_id']] = array(
'student_name' => $row['student_name'],
'questions' => array(),
);
}
$data[$row['student_id']]['questions'][] => array(
'question_id' => $row['question_id'],
'answer' => $row['answer'],
);
}
Which will give you this array :
$data = array(
'1' => array(
'student_name' => 'Ronaldo',
'questions' => array(
array(
'question_id' => 1,
'answer' => 'A',
),
array(
'question_id' => 2,
'answer' => 'D',
),
),
),
'2' => array(
'student_name' => 'Messi',
'questions' => array(
array(
'question_id' => 1,
'answer' => 'C',
),
array(
'question_id' => 2,
'answer' => 'B',
),
),
),
);
Finally, loop through the last array to display data the way you want :
foreach($data as $student){
echo $student['student_name'] . ' : ' ;
foreach($student['questions'] as $question){
echo 'Question ' . $question['question_id'] . ' : ' . $question['answer'] . "\n";
}
}
You will need to do some adaptation to suit your need.

combining rows in result

I have this data table:
+-ID-+-sensorID-+----date---+-value-+
| 1 | 1 |'some date'| 20 |
| 2 | 1 |'some date'| 15 |
| 3 | 1 |'some date'| 18 |
| 4 | 2 |'some date'| 40 |
| 5 | 2 |'some date'| 68 |
| 6 | 2 |'some date'| 55 |
Now I want to create an array like this in php:
date - value sensorID(1) - value sensorID(2)
I also need something to show whenever a date has a single sensor value:
[date] => 01-01-2014 [value] => 50 [value] => 60
[date] => 02-01-2014 [value] => 20 [value] => 30
[date] => 03-01-2014 [value] => null [value] => 55
[date] => 04-01-2014 [value] => 20 [value] => 33
How can I do this efficiently in some simple steps? Otherwise I would just create a result for ID 1 and ID 2 or run my function twice on the complete array.
Just get all the data in one run and construct the array in PHP:
// do the mysql query stuff >> $result (array of all rows in db)
$data = array();
foreach ($result AS $row) {
if (!isset($data[$row['date']])) {
$data[$row['date']] = array('sensor1' => null, 'sensor2' => null);
}
$data[$row['date']]['sensor' . $row['sensorID']] = $row['value'];
}
Result would be something like
$data = array(
'01-01-2014' => array('sensor1' => 50, 'sensor2' => 60),
'02-01-2014' => array('sensor1' => 20, 'sensor2' => 30),
'03-01-2014' => array('sensor1' => null, 'sensor2' => 55),
'04-01-2014' => array('sensor1' => 20, 'sensor2' => 33)
);

Categories