Merge indexed arrays from POST request - php

I have this array coming from post request:
$x = [
"meal" => [
"monday" => [
"breakfast" => [
0 => "type1",
1 => "type1",
],
"afternoonTea" => [
0 => "type2",
],
],
],
"number" => [
"monday" => [
"breakfast" => [
0 => "10",
1 => "9",
],
"afternoonTea" => [
0 => "1",
],
],
],
];
I am trying to merge all this into one array without using tones of foreaches.
Maybe someone more clever will know how to use iterators to achieve that.
Data from meal and number is always 1:1.
I need to convert this to something like this:
$x = [
"monday" => [
"breakfast" => [
[
'type' => "type1",
'number' => 10,
],
[
'type' => "type1",
'number' => 9
]
],
"afternoonTea" => [
[
'type' => "type2",
'number' => 1,
],
],
],
],
];

If you count 3 as being tonnes then this isn't your answer - but I can't see a way of reducing down the number of reach loops below this without getting to a game of code golf which won't be helpful.
Because you know there is a 1:1 relationship between meal and number, you can use the indexes from one to get data from the other by doing:
$result = [];
foreach($x['meal'] as $day => $list) {
foreach($list as $activity => $types) {
foreach($types as $i => $type) {
$result[$day][$activity][] = [
'type' => $type,
'value' => $x['number'][$day][$activity][$i],
];
}
}
}
The output of this will be $result will contain the array in the format you want.

Related

How to use MDword to generate multi-level nested Office Word?

effect picture:
https://i.stack.imgur.com/f2r3O.png
github address:
https://github.com/mkdreams/MDword
data:
$arr = [
[
"title1" => "title1",
"meeting_content"=>[
[
"title11" => "title11,title11",
"content11" => "content,content,content,content,content,content,content,content,content,"
],
[
"title22" => "title22,title22",
"content22" => "content,content,content,content,content,content,content,content,content,"
],
],
"children" => []
],
[
"title" => "title",
"meeting_content"=>[
],
"children"=>[
[
"title1" => "title1",
"meeting_content"=>[
[
"title11" => "title11,title11",
"content11" => "content,content,content,content,content,content,content,content,content,"
],
[
"title22" => "title22,title22",
"content22" => "content,content,content,content,content,content,content,content,content,"
],
],
],
[
"title2" => "title2",
"meeting_content"=>[
[
"title11" => "title11,title11",
"content11" => "content,content,content,content,content,content,content,content,content,"
],
[
"title22" => "title22,title22",
"content22" => "content,content,content,content,content,content,content,content,content,"
],
],
],
],
],
];
How to use MDword to generate multi-level nested Office Word?
Now I need to, using a MDword extension of PHP, write this multidimensional data into a Word document, I don't know what to do, it has the effect picture, and Github address, thank you
You can use pstyle.You can see the demo.
Details as follows(You must update to the latest version):
data
$numDatas = [
[
'title'=>'title-1',
'content'=>'content-1'
],
[
'title'=>'title-2',
'sub'=>[
[
'title'=>'subTitle-2-1',
'content'=>'content-2-1',
],
[
'title'=>'subTitle-2-2',
'content'=>'content-2-2',
],
]
],
[
'title'=>'title-3',
'sub'=>[
[
'title'=>'subTitle-3-1',
'content'=>'content-3-1',
],
[
'title'=>'subTitle-3-2',
'content'=>'content-3-2',
],
]
],
];
temple IMG:
https://i.stack.imgur.com/dS1U1.png
code
$TemplateProcessor->cloneP('num',count($numDatas));
foreach($numDatas as $idx => $numData) {
$TemplateProcessor->cloneP('num'.'#'.$idx,3);
$TemplateProcessor->setValue('num'.'#'.$idx.'#0',[['text' => $numData['title'], 'pstyle' => 'numstyle-level-1', 'type' => MDWORD_TEXT]]);
if(isset($numData['content'])) {
$TemplateProcessor->setValue('num'.'#'.$idx.'#1',[['text' => $numData['content'], 'pstyle' => 'numstyle-level-3', 'type' => MDWORD_TEXT]]);
}else{
$TemplateProcessor->deleteP('num'.'#'.$idx.'#1');
}
$subName = 'num'.'#'.$idx.'#2';
if(isset($numData['sub'])) {
$TemplateProcessor->cloneP($subName,count($numData['sub']));
foreach($numData['sub'] as $subIdx => $subData) {
$TemplateProcessor->cloneP($subName.'#'.$subIdx,2);
$TemplateProcessor->setValue($subName.'#'.$subIdx.'#0',[['text' => $subData['title'], 'pstyle' => 'numstyle-level-2', 'type' => MDWORD_TEXT]]);
$TemplateProcessor->setValue($subName.'#'.$subIdx.'#1',[['text' => $subData['content'], 'pstyle' => 'numstyle-level-3', 'type' => MDWORD_TEXT]]);
}
}else{
$TemplateProcessor->deleteP($subName);
}
}
$TemplateProcessor->deleteP('numstyle');
result IMG:
https://i.stack.imgur.com/sb0MB.png

How to get value of filtered spreadsheets using google sheets api?

i need to showing data from sheet based on user keyword.
i try using setBasicFilter to filter data.
Here example requestbody.
$query = [
'requests' => [
[
'setBasicFilter' => [
'filter' => [
'range' => [
'sheetId' => 0,
'startColumnIndex' => 0,
'endColumnIndex' => 14,
'startRowIndex' => 0
],
'sortSpecs' => [
[
'dimensionIndex' => 0,
'sortOrder' => 'DESCENDING'
],
[
'dimensionIndex' => 2,
'sortOrder' => 'ASCENDING'
]
],
'filterSpecs' => [
[
'columnIndex' => 2,
'filterCriteria' => [
'condition' => [
'type' => 'TEXT_CONTAINS',
'values' => [
[
'userEnteredValue' => 'input'
]
]
]
]
]
]
]
]
]
]
];
but, its only change view data on the spreadsheets, and response only return empty.
Do you have a solution for this problem?
I got the solution after seeing this issue Google Sheets API, Read Values by Filter
you can use foreach() than use if() to get data that you need to filter.
example :
foreach ($data['values'] as $key => $value) {
if($value[2] === 'input') {
// $key . $value
}
}

Filtering or possibly a mapping operation using collections in Laravel

Looks like I am probably having a dumb moment here. I have got a collection that I am trying to filter on basis of couple of conditions. Here is the array:
$files =[
[
"customisation_id" => "2357323",
"file_type" => 2,
"url" => "transparent/76caa009d0c2aa32793a8f48ad395dcb_616351.png.png"
],
[
"customisation_id" => "2357323",
"file_type" => 3,
"url" => "nonTransparent/5ae5a3ec64a35ebcaa26e211244c24a4_826308.jpg.png"
],
[
"customisation_id" => "2357324",
"file_type" => 2,
"url" => "transparent/5ae5a3ec64a35ebcaa26e211244c24a4_826308.jpg.gif"
],
[
"customisation_id" => "2357324",
"file_type" => 3,
"url" => "nonTransparent/64dc36fc492a87cf96f1fd2346e60dd3_560667.jpg.png"
],
[
"customisation_id" => "2357350",
"file_type" => 2,
"url" => "transparent/64dc36fc492a87cf96f1fd2346e60dd3_560667.jpg.gif"
],
[
"customisation_id" => "2357355",
"file_type" => 3,
"url" => "transparent/64dc36fc492a87cf96f1fd2346e60dd3_560667.jpg.gif"
]
];
I would like to create a new array out of it which has a file_type of 2 with no duplicate records with same customisation_id. However, if there isn't a repeating record in terms of customer_id then just add it to collection. NOTE: I am using arrays interchangeably with
collection as I am going to use collection for it. Ideally, I want a new array or collection with following structure:
$files =[
[
"customisation_id" => "2357323",
"file_type" => 2,
"url" => "transparent/76caa009d0c2aa32793a8f48ad395dcb_616351.png.png"
],
[
"customisation_id" => "2357324",
"file_type" => 2,
"url" => "transparent/5ae5a3ec64a35ebcaa26e211244c24a4_826308.jpg.gif"
],
[
"customisation_id" => "2357350",
"file_type" => 2,
"url" => "transparent/64dc36fc492a87cf96f1fd2346e60dd3_560667.jpg.gif"
],
[
"customisation_id" => "2357355",
"file_type" => 3,
"url" => "transparent/64dc36fc492a87cf96f1fd2346e60dd3_560667.jpg.gif"
]
];
I have already tried filter, map and reduce methods of collection which solves the first part of puzzle but then I get stuck with second condition.
Thank you!
$newArray = collect($files)->unique('customisation_id')->values()->all();
You should also read about intersect() : https://laravel.com/docs/6.x/collections#method-intersect

Custom sorting multidimensional with n items by highest value

I am currently able to sort a multidimensional array using a custom sorting method. Each array lineupSet has an n amount of items. The function sort_points will sort each lineupSet from highest to lowest totalPoints and then it will give me the lineupSet with the the highest total totalPoints. I am currently changing the approach, I still want to sort through each lineupSet first and order highest to lowest. Then I would like to get the highest totalPoints of each lineupSet based on a given count. What would be the best way to approach this?
Test Array:
$testArray = [[
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.61,
],
"name" => "arr0-test0",
], [
"formula" => [
"totalPoints" => 201.17,
],
"name" => "arr0-test1",
]], [
"formula" => [
"totalPoints" => 5.01,
],
"name" => "arr0-test2",
]],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.76,
],
"name" => "arr1-test0",
], [
"formula" => [
"totalPoints" => 220.66,
],
"name" => "arr1-test1",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.71,
],
"name" => "arr2-test0",
], [
"formula" => [
"totalPoints" => 204.43,
],
"name" => "arr2-test1",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.48,
],
"name" => "arr3-test0",
], [
"formula" => [
"totalPoints" => 203.51,
],
"name" => "arr3-test1",
]],
],
]];
Sorting Function
function sum_points($v) {
$totalPoints = 0;
foreach ($v['lineupSet'] as $lset) {
if (isset($lset['formula'])) {
$totalPoints += $lset['formula']['totalPoints'];
}
else {
foreach ($lset as $l) {
$totalPoints += $l['formula']['totalPoints'];
}
}
}
return $totalPoints;
}
function sort_points($a, $b) {
return sum_points($b) - sum_points($a);
}
usort($testArray, 'sort_points');
print_r($testArray[0]);
For example I want to get the top two highest 'totalPoints'. The desired outcome:
Array (
[lineupSet] => Array
(
[0] => Array
(
[0] => Array
(
[formula] => Array
(
[totalPoints] => 220.66
)
[name] => arr1-test1
)
[1] => Array
(
[formula] => Array
(
[totalPoints] => 214.76
)
[name] => arr0-test0
)
)
)
)
I want to do the same for the top n highest totalPoints. Keeping in mind that it will have to take at times n items from each lineupSet that are the highest totalPoints.
I think it's better to use an object then you can keep max while you are sorting data (also you can use a constructor to sort the array).
Class SortHelper{
public $max = 0;
private function checkMax($totalPoints){
if($totalPoints > $this->max)
$this->max = $totalPoints;
}
private function sum_points($v) {
$totalPoints = 0;
foreach ($v['lineupSet'] as $lset) {
if (isset($lset['formula'])) {
$totalPoints += $lset['formula']['totalPoints'];
$this->checkMax($lset['formula']['totalPoints']);
}
else {
foreach ($lset as $l) {
$totalPoints += $l['formula']['totalPoints'];
$this->checkMax($l['formula']['totalPoints']);
}
}
}
return $totalPoints;
}
private function sort_points($a, $b) {
return $this->sum_points($b) - $this->sum_points($a);
}
public function sort($array){
usort( $array, [$this, 'sort_points']);
return $array;
}
}
then you would have:
$sortHelper = new SortHelper();
$sorted_array = $sortHelper->sort($testArray);
var_dump($sorted_array[0]);
var_dump($sortHelper->max);
Check this out,
$n = 2; // number of elements
$testArray = [[
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.61,
],
"name" => "arr0-test0",
], [
"formula" => [
"totalPoints" => 201.17,
],
"name" => "arr0-test1",
]], [
"formula" => [
"totalPoints" => 5.01,
],
"name" => "arr0-test2",
]
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.76,
],
"name" => "arr1-test0",
], [
"formula" => [
"totalPoints" => 220.66,
],
"name" => "arr1-test1",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.71,
],
"name" => "arr2-test0",
], [
"formula" => [
"totalPoints" => 204.43,
],
"name" => "arr2-test1",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.48,
],
"name" => "arr3-test0",
], [
"formula" => [
"totalPoints" => 203.51,
],
"name" => "arr3-test1",
]],
],
]];
function sort_points($a, $b)
{
return ($a['formula']['totalPoints'] > $b['formula']['totalPoints']) ? -1 : 1;
}
$result = [];
$reference = &$result['lineupSet'][0]; // store reference in $reference
foreach ($testArray as $tA) {
foreach ($tA['lineupSet'] as $t) {
foreach ($t as $child) {
$reference[] = $child;
}
}
}
usort($reference, 'sort_points');
$reference = array_slice($reference, 0, $n);
var_dump($result); // desired output
Please try this 2 functions, the steps as follows:
sort_points(); Sort it with arsort PHP function and return it to new simplified array.
transform_arrays($sortedArray, $testArray); $testArray will be changed the value by the sortedArray.
copy all the codes into single file of .php and run it.
*i assume that we don't care about the complexity, also in real life (in this case my life) there is nothing such the case that you need to sort in multidimensional array, because array is just the storage to keep the data can be read by human.
<?php
$testArray =
[
['lineupSet' => [[['formula' => ['totalPoints' => 214.61],'name' => 'arr0-test0'],['formula' => ['totalPoints' => 220.66],'name' => 'arr1-test1']]]],
['lineupSet' => [[['formula' => ['totalPoints' => 205.71],'name' => 'arr2-test0'],['formula' => ['totalPoints' => 204.43],'name' => 'arr2-test1']]]],
['lineupSet' => [[['formula' => ['totalPoints' => 205.48],'name' => 'arr3-test0'],['formula' => ['totalPoints' => 203.51],'name' => 'arr3-test1']]]]
];
// sort into another array
function sort_points($testArray = []){
$response = $result = [];
$i = 0;
foreach($testArray as $array2){
foreach($array2['lineupSet'][0] as $item){
$result[$item['name']] = $item['formula']['totalPoints'];
$i++;
}
}
arsort($result);
$i = 0;
foreach($result as $key => $val){
$response[$i]['name'] = $key;
$response[$i]['totalPoints'] = $val;
$i++;
}
return $response;
}
// this won't work if the $testArray format structure is changed
function transform_arrays($items, $testArray){
$l = 0;
for($i=0;$i<count($testArray);$i++){
for($j=0;$j<count($testArray[$i]);$j++){
for($k=0;$k<count($testArray[$i]['lineupSet'][$j]);$k++){
$testArray[$i]['lineupSet'][$j][$k]['formula']['totalPoints'] = $items[$l]['totalPoints'];
$testArray[$i]['lineupSet'][$j][$k]['name'] = $items[$l]['name'];
// print_r($testArray[$i]['lineupSet'][$j][$k]['formula']['totalPoints']);
// print_r($testArray[$i]['lineupSet'][$j][$k]);
$l++;
}
}
}
return $testArray;
}
echo '<pre>';
$sortedArray = sort_points($testArray);
$response = transform_arrays($sortedArray, $testArray);
print_r($response);
echo '</pre>';

How to push items into array in php

I am using Laravel with ES and trying to build a dynamic query.
But the following doesnt work:
$query[] = ['term' => ['city' => 1]];
$query[] = ['term' => ['state' => 2]];
$query[] = ['range' => ['price' => ['lte' => 2]]];
$asd = ['filtered' => [
'query' => [
'match' => ['title' => Input::get('query')]
],
'filter'=> [
'bool' => [
'must' => [
['term' => [ 'is_active' => 1] ],
[ 'range' => [
'end_date' => [
'from' => 'now'
]
]
],
$query
]
]
],
],];
echo json_encode($asd);
This will append $query[] wrong into $asd, like:
{"term":{"is_active":1}},
{"range":{"end_date":{"from":"now"}}},
[
{"term":{"city":1}},
{"term":{"state":2}},
{"range":{"price":{"lte":2}}}
]
How I would like to append it is:
{"term":{"is_active":1}},
{"range":{"end_date":{"from":"now"}}},
{"term":{"city":1}},
{"term":{"state":2}},
{"range":{"price":{"lte":2}}}
without the [] around it.
Solved:
$asd = ['filtered' => [
'query' => [
'match' => ['title' => Input::get('query')]
],
'filter'=> [
'bool' => [
'must' =>
$query
]
],
],];
A valid json string always consist of a single object or an array of objects.
The string you are asking for is not legal json, it would not be possible to parse.
Json with a single object looks like this:
{ // Object start.
"property": "value" // Where value could be a object or array or whatever.
} // Object end.
And if an array:
[ // Array start.
"Array value" // which could be an object or another array or whatever.
] // Array end.
When you convert your PHP array containing associative arrays, it will be converted into a string containing a array of objects.
You could always remove the [] from the string if you wish it to look like you described, but it will not be valid json.
Edit:
An elastic query looks basically like this:
{
"query": {
"term": { data ... }
}
}
I'm guessing that what you want/need to do is to create the php array like this:
$query = [
'query' => [
'term' => [
'state' => 2
'city' => 1
],
'range' => [
'price' => [
'lte' => 2
]
]
]
]
Which would result in a JSON string that looks like this:
{
"query":
{
"term":
{
"state": 2,
"city": 1
},
"range":
{
"lte": 2
}
}
}

Categories