I have two arrays that are the results of two different database queries. I want to merge those two arrays fin the way I explain in the example below
This is the code that executes the first query:
$query = $this->db->query("SELECT kec,pilihan,COUNT(pilihan) as total FROM votes GROUP BY pilihan");
$someArray = [];
foreach($query->result_array() as $row){
array_push($someArray, [
'data' => $row['pilihan'],
'total' => $row['total'],
'location' => $row['kec'],
]);
}
This is the resulting array:
[
{
"data": "1",
"total": "2",
"location": "3524230"
},
{
"data": "2",
"total": "3",
"location": "3524230"
},
{
"data": "3",
"total": "1",
"location": "3524230"
}
]
This is the code that executes the second query:
$query = $this->db->query("SELECT * FROM owl_dptmaster GROUP BY kecamatan");
$someArray = [];
foreach($query->result_array() as $row){
array_push($someArray, [
'location' => $row['kecamatan']
]);
}
And the second array looks like this:
[
{
"location": "3524230"
},
{
"location": "3524240"
},
{
"location": "3524250"
},
{
"location": "3524260"
}
]
I want to merge those two arrays so that the result would be this array:
[
{
"location": "3524230",
"data1": "2",
"data2": "3",
"data3": "1"
},
{
"location": "3524240",
"data1": null,
"data2": null,
"data3": null
},
{
"location": "3524250",
"data1": null,
"data2": null,
"data3": null
},
{
"location": "3524260",
"data1": null,
"data2": null,
"data3": null
}
]
How can I achieve this?
Instead of combining arrays, you could do the summarizing in sql with sub queries. Assuming you're using mysql.
$query = $this->db->query(
"select owl.kecamatan,
(select count(pilihan) from votes where kec = owl.kecamatan and pilihan = 1) data1,
(select count(pilihan) from votes where kec = owl.kecamatan and pilihan = 2) data2,
(select count(pilihan) from votes where kec = owl.kecamatan and pilihan = 3) data3,
from owl_dptmaster owl
order by owl.kecamatan"
);
You could do this query and then build an array of "data" . $pilihan => $totalPilihan which you push into the $someArray when the $location changes.
$query = $this->db->query(
"select owl.kecamatan as location, v.pilihan
from owl_dptmaster owl
left join votes v
on owl.kecamatan = v.kec"
order by 1, 2);
You have a results set with all the locations and votes.
// Made of query results...
$query = [
[ "location" => "3524230", "pilihan" => "1" ],
[ "location" => "3524230", "pilihan" => "1" ],
[ "location" => "3524230", "pilihan" => "2" ],
[ "location" => "3524230", "pilihan" => "3" ],
[ "location" => "3524230", "pilihan" => "3" ],
[ "location" => "3524230", "pilihan" => "3" ],
[ "location" => "3524230", "pilihan" => "4" ],
[ "location" => "3524230", "pilihan" => "4" ],
[ "location" => "3524230", "pilihan" => "5" ],
[ "location" => "3524240", "pilihan" => null ],
[ "location" => "3524250", "pilihan" => null ],
[ "location" => "3524260", "pilihan" => null ],
[ "location" => "3524270", "pilihan" => "1" ],
[ "location" => "3524270", "pilihan" => "1" ],
[ "location" => "3524270", "pilihan" => "1" ],
[ "location" => "3524270", "pilihan" => "20" ],
[ "location" => "3524270", "pilihan" => "20" ],
[ "location" => "3524270", "pilihan" => "30" ]
];
And here's a procedural routine to build $someArray[].
$someArray = [];
$xRow = [];
$oldPilihan = '';
$total = 0;
$oldLocation = '';
foreach ($query as $row) {
//echo $row['location'] . " - " . $row['pilihan'] . '<br>';
$location = $row['location'];
$pilihan = $row['pilihan'];
if ($pilihan !== $oldPilihan) {
if (! empty($oldPilihan) ) {
$dataName = 'data' . $oldPilihan;
$xRow[] = array($dataName => $total);
}
$total = 1;
$oldPilihan = $pilihan;
} else {
$total++;
}
if ($location !== $oldLocation) {
if (! empty($oldLocation)) {
array_push($someArray, $xRow);
}
$xRow = [ 'location' => $location ];
$oldLocation = $location;
}
}
$dataName = 'data' . $oldPilihan;
$xRow[] = array($dataName => $total);
array_push($someArray, $xRow);
var_dump($someArray);
Related
I have this php code as I am trying to execute a particular function in my php project, I code the implementation correct but I ran into a small problem.
<?php echo '<script type="text/javascript">';
$data = array(
'base' => 'USD',
'alter' => 'ETH',
'data' => array()
);
foreach ($cryptos as $row) {
$sy = $row["symbol"];
$data['data'][] = array(
"$sy" => [
"rate" => 1.552000000000000,
"min" => 1.0077600000000000,
"max" => 10.077600000000000,
"code" => $row["symbol"],
"dp" => 8
],
);
}
print_r("var fxCur = " . json_encode($data));
Running the code above I got this result below, That's the expected result but I want to omit [] between data
{
"base":"USD",
"alter":"ETH",
"data":[
{
"BTC":{
"rate": 1.552000000000000,
"min": 1.0077600000000000,
"max": 10.077600000000000,
"code":"BTC",
"dp":8
}
},
{
"ETH":{
"rate": 1.552000000000000,
"min": 1.0077600000000000,
"max": 10.077600000000000,
"code":"ETH",
"dp":8
}
}
]
}
But actually I wanted this result
{
"base":"USD",
"alter":"ETH",
"data":{
"BTC":{
"rate": 1.552000000000000,
"min": 1.0077600000000000,
"max": 10.077600000000000,
"code":"BTC",
"dp":8
},
"ETH":{
"rate": 1.552000000000000,
"min": 1.0077600000000000,
"max": 10.077600000000000,
"code":"ETH",
"dp":8
},
}
}
You're telling it to construct the data structure that way.
$data['data'][] = array(
"$sy" => [
...
]
);
That line says "append an element to $data['data'] at the next integer index and set it equal to the array e.g. [ "BTC" => [ ... ]]
I think what you want is:
$data['data'][$sy] = [
"rate" => 1.552000000000000,
"min" => 1.0077600000000000,
"max" => 10.077600000000000,
"code" => $row["symbol"],
"dp" => 8
];
Intuit integration.
With create invoice. I am needing to get items from a loop when I create the invoice.
I also tried by creating the loop first and using $items in the invoice create but also get an error. "Format Error. Expect an element of an array or an object."
Not liking my loop. How can I accomplish this
?
$theResourceObj = Invoice::create([
"TotalAmt" => 200.00,
"Line" => [
$queryitems = 'SELECT * FROM mydatabse',
$query_items = mysqli_query($con,$queryitems),
while($row = mysqli_fetch_array($query_items)) {
[
"Description"=> "Loop Description",
"DetailType"=> "SalesItemLineDetail",
"SalesItemLineDetail"=> [
"TaxCodeRef"=> [
"value"=> "TAX"
],
"Qty"=> 1,
"UnitPrice"=> 200,
"ItemRef"=> [
"name"=> "Loop Name",
"value"=> "5"
]
],
"LineNum"=> 1,
"Amount"=> 200.00,
"Id"=> "1"
],
}
],
"CustomerRef"=> [
"value"=> 1
],
"BillEmail" => [
"Address" => "email#somewhere.com"
]
]);
You can't put loops inside array literals.
Construct the array incrementally outside the call to Invoice::create().
$invoice = [
"TotalAmt" => 200.00,
"CustomerRef"=> [
"value"=> 1
],
"BillEmail" => [
"Address" => "email#somewhere.com"
]
];
$lines = [];
$queryitems = 'SELECT * FROM mydatabse';
$query_items = mysqli_query($con,$queryitems);
while($row = mysqli_fetch_array($query_items)) {
$lines[] = [
"Description"=> "Loop Description",
"DetailType"=> "SalesItemLineDetail",
"SalesItemLineDetail"=> [
"TaxCodeRef"=> [
"value"=> "TAX"
],
"Qty"=> 1,
"UnitPrice"=> 200,
"ItemRef"=> [
"name"=> "Loop Name",
"value"=> "5"
]
],
"LineNum"=> 1,
"Amount"=> 200.00,
"Id"=> "1"
];
}
$invoice['Line'] = $lines;
$theResourceObj = Invoice::create($invoice);
I am trying to modify single field value, but whenever I do it it erases all other fields leaving updated field only, how can I modify a single field witouth affecting the other ones?
so far this is what I'm doing:
//
$updateResult2 = $coll_rutas->updateOne(
/* LIMIT TO ROUTE ID */
[
"_id" => new \MongoDB\BSON\ObjectId($ruta_id)
],
/* UPDATE VALUE */
[
'$set' => [
'destinos.$[d]' => [
"horas" => "1",
"minutos" => "15",
"millas" => "150",
"orden" => "1",
"notas" => "demo notes",
],
],
],
/* WHERE FILTER */
[
"upsert" => true,
'arrayFilters' => [
['d.ciudad_id' => 47]
]
]
);
//var_dump($updateResult2); exit;
This is the original mongo Object:
"destinos": [
{
"ciudad_id": "47",
"nombre_destino": "Salt Lake City, Utah",
"horas": "0",
"minutos": "0",
"millas": "0",
"orden": 1,
"notas": null,
"origenes": [
{
"ciudad_id": "45",
"nombre_origen": "Provo, Utah",
"orden": 1,
"notas": null,
"base_price": 0
}
]
}
],
With my changes it erases origenes array, ciudad_id and nombre destino, leaving it this way:
"destinos": [
{
"horas": "1",
"minutos": "15",
"millas": "150",
"orden": "1",
"notas": "demo notes"
]
}
],
With this code:
'$set' => [
'destinos.$[d]' => [
"horas" => "1",
"minutos" => "15",
"millas" => "150",
"orden" => "1",
"notas" => "demo notes",
],
]
you are targeting the destinos.$[d] element and replacing all of its contents with the new data structure.
You need to use the .(dot) notation to target each element in the nested array. It's a bit verbose but this would work:
'$set' => [
'destinos.$[d].horas' => "1",
'destinos.$[d].minutos' => "15",
'destinos.$[d].millas' => "150",
'destinos.$[d].orden' => "1",
'destinos.$[d].notas' => "demo notes"
]
I have an SQL Query returning certain fields, I am using json_encode() to get the data in JSON format, however I am having trouble getting it in the format I want.
PHP Code
<?php
function data() {
$runDistanceBasedOnCityQuery = "SELECT rc.id, rc.cityId, c.cityName, rc.runId, r.distance, rc.status FROM run_city rc INNER JOIN cities c ON c.id = rc.cityId INNER JOIN run_distance r ON r.id = rc.runId ORDER BY c.cityName";
$runDistanceBasedOnCityResult = $db->prepare($runDistanceBasedOnCityQuery);
$runDistanceBasedOnCityResult->bindParam(":cityId", $cityId, PDO::PARAM_INT);
$runDistanceBasedOnCityResult->execute();
$runDistanceBasedOnCityOutput = $runDistanceBasedOnCityResult->rowCount();
if ($runDistanceBasedOnCityOutput > 0) {
while ($runDistanceBasedOnCityRow = $runDistanceBasedOnCityResult->fetch(PDO::FETCH_ASSOC)) {
$array1 = array($runDistanceBasedOnCityRow['runId'], $runDistanceBasedOnCityRow['distance'], $runDistanceBasedOnCityRow['status']);
for ($i = 0; $i < sizeof($array1); $i++) {
$array2 = array("id" => $runDistanceBasedOnCityRow['id'], "runId" => $runDistanceBasedOnCityRow['cityId'], $runDistanceBasedOnCityRow['cityName'] => $array1);
}
$finalResultRunDistanceBasedOnCity[] = $array2;
}
$responseRunDistanceBasedOnCity = $finalResultRunDistanceBasedOnCity;
} else {
$responseRunDistanceBasedOnCity = 'Runs not found';
}
$result = array("status" => true,
"runsBasedOnCity" => $responseRunDistanceBasedOnCity
);
json($result);
}
function json($data) {
header('Content-Type:application/json');
if (is_array($data)) {
echo json_encode($data);
}
}
?>
The JSON format I am getting
"runsBasedOnCity": [
{
"id": "1",
"runId": "1",
"Bengaluru": [
"2",
"10k",
"1"
]
},
{
"id": "2",
"runId": "1",
"Bengaluru": [
"1",
"5k",
"1"
]
},
{
"id": "3",
"runId": "1",
"Bengaluru": [
"5",
"3k",
"0"
]
},
{
"id": "4",
"runId": "2",
"Chennai": [
"1",
"5k",
"1"
]
},
{
"id": "5",
"runId": "2",
"Chennai": [
"2",
"10k",
"1"
]
},
{
"id": "6",
"runId": "2",
"Chennai": [
"4",
"15k",
"1"
]
}
]
The Format I Require
"runsBasedOnCity": [
{
"id": "1",
"cityId": "1",
"Bengaluru":
[
{
runId : "2",
distance : "10k",
status : "1"
},
{
runId : "1",
distance: "5k",
status : "1"
},
{
runId : "5",
distance : "3k",
status : "0"
}
]
},
{
"id": "2",
"cityId": "2",
"Chennai":
[
{
runId : "1",
distance : "5k",
status : "1"
},
{
runId : "2",
distance: "10k",
status : "1"
},
{
runId : "4",
distance : "15k",
status : "1"
}
]
}
I am not able to figure out a better way of doing this, I am fairly new to this, do help me out. Thanks !
To efficiently group the subarray data, you should implement temporary keys. cityId is a suitable value to group by -- because cityNames may intentionally duplicate in the future but cityId must never un/intentionally duplicate in your database table.
When each new cityId is encountered, the conditional isset() call will determine whether a new/full set of data should be stored, or if data should merely be appended to the subarray.
I am calling array_slice() since it cuts down on unnecessary syntax / code-bloat.
After iterating through all of the rows, you can reindex the $result array, nest it inside runBasedOnCity, and add the status element.
I'll show my demo with PRETTY_PRINT so that it is easier to read, but in your actual code, you should remove the parameter. Also, a word of advice -- try to keep your variable names brief for improved readability.
Code: (Demo)
$resultset = [
["id" => "1", "cityId" => "1", "cityName" => "Bengaluru", "runId" => "2", "distance" => "10k", "status" => "1"],
["id" => "2", "cityId" => "1", "cityName" => "Bengaluru", "runId" => "1", "distance" => "5k", "status" => "1"],
["id" => "3", "cityId" => "1", "cityName" => "Bengaluru", "runId" => "5", "distance" => "3k", "status" => "0"],
["id" => "4", "cityId" => "2", "cityName" => "Chennai", "runId" => "1", "distance" => "5k", "status" => "1"],
["id" => "5", "cityId" => "2", "cityName" => "Chennai", "runId" => "2", "distance" => "10k", "status" => "1"],
["id" => "6", "cityId" => "2", "cityName" => "Chennai", "runId" => "4", "distance" => "15k", "status" => "1"]
];
foreach ($resultset as $row) {
if (!isset($result[$row["cityId"]])) {
$result[$row["cityId"]] = array("id" => $row["id"], "cityId" => $row["cityId"], $row["cityName"] => array(array_slice($row,-3)));
} else {
$result[$row['cityId']][$row["cityName"]][] = array_slice($row,-3);
}
}
if (!isset($result)) { // don't need to check rowCount() at all
$result = 'Runs not found';
} else {
$result = array_values($result);
}
$result = array("status" => true, "runsBasedOnCity" => $result);
var_export(json_encode($result, JSON_PRETTY_PRINT));
Output:
'{
"status": true,
"runsBasedOnCity": [
{
"id": "1",
"cityId": "1",
"Bengaluru": [
{
"runId": "2",
"distance": "10k",
"status": "1"
},
{
"runId": "1",
"distance": "5k",
"status": "1"
},
{
"runId": "5",
"distance": "3k",
"status": "0"
}
]
},
{
"id": "4",
"cityId": "2",
"Chennai": [
{
"runId": "1",
"distance": "5k",
"status": "1"
},
{
"runId": "2",
"distance": "10k",
"status": "1"
},
{
"runId": "4",
"distance": "15k",
"status": "1"
}
]
}
]
}'
After explaining how you wanted to preserve the id values in the subarrays, here is that solution:
Code: (Demo)
foreach ($resultset as $row) {
if (!isset($result[$row["cityId"]])) {
$result[$row["cityId"]] = array("cityId" => $row["cityId"], $row["cityName"] => array(array("id" => $row["id"])+array_slice($row,-3)));
} else {
$result[$row['cityId']][$row["cityName"]][] = array("id" => $row["id"])+array_slice($row,-3);
}
}
if (!isset($result)) { // don't need to check rowCount() at all
$result = 'Runs not found';
} else {
$result = array_values($result);
}
$result = array("status" => true, "runsBasedOnCity" => $result);
var_export(json_encode($result, JSON_PRETTY_PRINT));
I have an array like this
$a = [
[
"id" => "1",
"values" => [
"1",
"2"
]
],
[
"id" => "2",
"values" => [
"1",
"3"
]
],
[
"id" => "3",
"values" => [
"2",
"4"
]
],
[
"id" => "4",
"values" => [
"4",
"6"
]
],
];
to search and return the array that 'values' has 2
$result = [
[
"id" => "1",
"values" => [
"1",
"2"
]
],
[
"id" => "3",
"values" => [
"2",
"4"
]
],
];
Yes, I can do with for loop, and use in_array to return the result, just thinking whether there is elegant (better) way to do it?
$result = [];
foreach ($a as $datum) {
if (in_array('2', $datum['values'])) {
$result[] = $datum;
}
}
I tried array_search, but it does not support nested array
array_search('2', array_column($a, 'values'));
You can use array_filter() and in_array():
$value = '2';
$result = array_filter($a, function (array $element) use ($value) {
return array_key_exists('values', $element)
&& is_array($element['values'])
&& in_array($value, $element['values'], true);
});
var_dump($result);
For reference, see:
http://php.net/manual/en/function.array-filter.php
http://php.net/manual/en/function.in-array.php
For an example, see:
https://3v4l.org/4HnFV