Distribute array row data to make multiple new rows - php

I have below the data
[
{
"price_in_dollar": 1000,
"price_in_euro": 1000,
"price_in_pound": 1000,
"price_in_rupee": 1000,
"toy_id": 1,
"toy_name": "Truck"
},
{
"price_in_dollar": 1000,
"price_in_euro": 1000,
"price_in_pound": 1000,
"price_in_rupee": 1000,
"toy_id": 2,
"toy_name": "Bicycle"
}
]
I want to create a new array from above as below
[
{
"toy": "Truck",
"toy_id": 1,
"rate": 1000,
"slug": "price_in_dollar",
},
{
"toy": "Truck",
"toy_id": 1,
"rate": 1000,
"slug": "price_in_euro",
},
...
{
"toy": "Bicycle",
"toy_id": 2,
"rate": 1000,
"slug": "price_in_dollar",
},
{
"toy": "Bicycle",
"toy_id": 2,
"rate": 1000,
"slug": "price_in_euro",
},
...
]
I have tried the below code
foreach($data as $r) {
foreach($r as $key => $value) {
if ($key === 'toy_name') {
$cars['toy'] = $value ;
}
else if ($key === 'toy_id') {
$cars['toy_id'] = $value;
}
else {
$cars['slug'] = $key ;
$cars['rate'] = $value;
}
}
}
But it only has one set of data, how can I append all data? Or any improved code to solve this?

your code was actually replacing a key => value pair data, not pushing a data into $cars, you can fix it like this:
$cars = [];
foreach($data as $r) {
$singleCar = [
"toy_id" => $r['toy_id'],
"toy" => $r['toy_name'],
];
foreach($r as $key => $val){
if($key != 'toy_id' && $key != 'toy_name') {
$singleCar['rate'] = $val;
$singleCar['slug'] = $key;
$cars[] = $singleCar;
}
}
}

Something like the below is working fine:
$data= [
[
"price_in_dollar" => 1000,
"price_in_euro" => 1000,
"price_in_pound" => 1000,
"price_in_rupee" => 1000,
"toy_id" => 1,
"toy_name" => "Truck"
],
[
"price_in_dollar" => 1000,
"price_in_euro" => 1000,
"price_in_pound" => 1000,
"price_in_rupee" => 1000,
"toy_id" => 2,
"toy_name" => "Bicycle"
]
];
$cnt = 0;
foreach($data as $r) {
foreach($r as $key => $value) {
if ($key === 'toy_name') {
$cars[$cnt]['toy'] = $value ;
}
else if ($key === 'toy_id') {
$cars[$cnt]['toy_id'] = $value;
}
else {
$cars[$cnt]['slug'] = $key ;
$cars[$cnt]['rate'] = $value;
}
}
$cnt++;
}
// display result
print_r($cars);

try like
foreach($data as $r) {
foreach($r as $key => $value) {
if ($key === 'toy_name') {
$cars[]['toy'] = $value ;
}
else if ($key === 'toy_id') {
$cars[]['toy_id'] = $value;
}
else {
$cars[]['slug'] = $key ;
$cars[]['rate'] = $value;
}
}
}

I would loop for the different currencies and use some php array functions
$currencies = ['price_in_dollar', 'price_in_euro', 'price_in_pound', 'price_in_rupee'];
$data= [
...
];
$newData = [];
foreach($currencies as $currency) {
$newData = array_merge(
$newData,
array_map(function ($item) use ($currency) {
return [
"toy" => $item['toy_name'],
"toy_id" => $item['toy_id'],
"rate" => $item[$currency],
"slug" => $currency,
];
}, $data)
);
}

As you iterate each row, isolate the repeatable elements, then removed them from the row, then iterate the remaining elements and push the new desired associative rows into the result array.
The unset() call will not actually affect the original input array because the forearch is actually iterating a "copy" of the input array.
Code: (Demo)
$result = [];
foreach ($data as $row) {
['toy_id' => $id, 'toy_name' => $name] = $row;
unset($row['toy_id'], $row['toy_name']);
foreach ($row as $slug => $rate) {
$result[] = compact(['id', 'name', 'slug', 'rate']);
}
}
var_export($result);

Related

PHP merge array by "depth"? [duplicate]

This question already has answers here:
How to array_merge_recursive() an array?
(2 answers)
Closed 3 months ago.
I have an array like this:
[
{
"function_1": {
"element": {
"error": "0",
"msg": "test"
}
}
},
{
"function_1": {
"element_2": {
"error": "0",
"msg": "test"
}
}
},
{
"function_2": {
"element": {
"error": "0",
"msg": "test"
}
}
},
{
"function_2": {
"element_2": {
"error": "0",
"msg": "test"
}
}
}
]
I want output like this:
[
{
"function_1": {
"element": {
"error": "0",
"msg": "test"
},
"element_2": {
"error": "0",
"msg": "test"
}
}
},
{
"function_2": {
"element": {
"error": "0",
"msg": "test"
},
"element_2": {
"error": "0",
"msg": "test"
}
}
}
]
The answers that I found offered to search by name("function_1", "function_2"). But this does not suit me, the function will not always pass an array. I need exactly the "depth" or any other reasonable way.
Thank you!
To achieve your desired result, you could json-decode, recursively merge each individual subarray, then loop over that structure to push each item as a second-level array like this: (Demo)
$array = json_decode($json, true);
$merged = array_merge_recursive(...$array);
$result = [];
foreach ($merged as $key => $data) {
$result[] = [$key => $data];
}
var_export($result);
But I can't imagine getting any benefit from adding unnecessary depth to your result array. I recommend simply json decoding, then calling array_merge_recursive() with the spread operator: (Demo)
var_export(
array_merge_recursive(
...json_decode($json, true)
)
);
Output:
array (
'function_1' =>
array (
'element' =>
array (
'error' => '0',
'msg' => 'test',
),
'element_2' =>
array (
'error' => '0',
'msg' => 'test',
),
),
'function_2' =>
array (
'element' =>
array (
'error' => '0',
'msg' => 'test',
),
'element_2' =>
array (
'error' => '0',
'msg' => 'test',
),
),
)
Your data structure looks weird for the purpose you are trying to achieve I'm bored af tho and created this code for you
function combineElementsPerfunction($functions) {
$result = [];
$uniqueFunctions = [];
foreach ($functions as $function) {
$functionName = array_keys($function)[0];
$uniqueFunctions[] = $functionName;
}
$uniqueFunctions = array_unique($uniqueFunctions);
foreach ($uniqueFunctions as $uniqueFunction) {
$functionObjects = array_filter(
$functions,
function($function) use ($uniqueFunction) {
$functionName = array_keys($function)[0];
return $functionName === $uniqueFunction;
}
);
$elements = [];
foreach ($functionObjects as $functionObject) {
$function = array_shift($functionObject);
$elements = array_merge($elements, $function);
}
$result[] = [
$uniqueFunction => $elements
];
}
return $result;
}
function changeArr($data){
$box = $new = [];
foreach ($data as $v){
$key = array_key_first($v);
$i = count($box);
if(in_array($key, $box)){
$keys = array_flip($box);
$i = $keys[$key];
}else{
$box[] = $key;
}
$new[$i][$key] = isset($new[$i][$key]) ? array_merge($new[$i][$key], $v[$key]) : $v[$key];
}
return $new;
}

php sum values based on same same ids in an array

I want to sum input['amount'] in given array only if input['ids'] are same. Please tell any best solution. Thanks
$input = [
'ids' => [1, 2, 3, 1],
'amount' => [50, 100, null, 100]
];
$result = [];
foreach ($input['ids'] as $key => $value) {
echo $key . ' = ' . $value . '<br>';
if($key == $key) {
$result['amount'] += $input['amount'][$key];
}
}
// I want this result form input array. thanks
$result = [
'ids' => [1, 2, 3],
'amount' => [150, 100, null]
];
// new array, ids => amount
$ids = array_unique($input['ids']);
// intialise to 0
foreach($ids as $id) {
$tempMap[$id] = 0;
}
// sum
foreach(array_values($input['amount']) as $i => $amount) {
if (is_null($amount)) {
$tempMap[ $input['ids'][$i] ] = $amount;
} else {
$tempMap[ $input['ids'][$i] ] += $amount;
}
}
$result['ids'] = array_keys($tempMap);
$result['amount'] = array_values($tempMap);
Use an associative array to hold the sums.
$sums = [];
foreach ($input['ids'] AS $index => $id) { // loop over the IDs
if ($input['amount'][$index] !== null) { // check if the corresponding amount is not null
$sums[$id] += $input['amount'][$index]; // Add it to the associative array that's keyed by ID
}
}
$result = [];
$result['ids'] = array_unique($input['ids']); // find all the different IDs
$result['amount'] = array_map(function($id) use($sums) {
return $sums[$id] ?? null; // for each ID, return the sum, or null if all the corresponding amounts were null
}, $result['ids']);

How do I put multiple values in an array while foreaching through values in PHP

Alright so I'm trying to adjust an array and decode it to json, currently it decodes the array like this;
{"campaignId":"18210f12-502c-4d71-a098-4f595304a8d0","fields.CPLastName":"Voornaam 1","fields.CPFirstname":"Achternaam 1","fields.OROrganisation":"Bedrijf 1"}
{"campaignId":"18210f12-502c-4d71-a098-4f595304a8d0","fields.CPLastName":"Voornaam 2","fields.CPFirstname":"Achternaam 2","fields.OROrganisation":"Bedrijf 2"}
Code:
$request = array();
foreach($address_data as $address) {
foreach($address as $key => $value){
if($key == 'campaignId') {
$request[$key] = $value;
}
if (strpos($key, 'fields') !== false) {
$fields = explode('.', $key);
$request['fields'] = array(
array('fieldId' => $fields[1], 'value' => $value)
);
}
}
echo json_encode($request);
}
What I want to do is, where it says; fields. I want to explode on that and replace fields. with fieldId within a fields array. So something like this;
$request['fields'] = array(array('fieldId' => $key, 'value' => $value));
Now for some reason it will only do the last key, and I want it to loop through all the keys where it says 'fields.'
So the final request should look something like;
{
"campaignId":"18210f12-502c-4d71-a098-4f595304a8d0",
"fields": [
{
"fieldId":"CPLastName",
"value":"Voornaam 1"
},
{
"fieldId": "CPFirstname",
"value": "Achternaam 1"
},
{
"fieldId":"OROrganisation",
"value":"Bedrijf 1"
}
]
}
{
"campaignId":"18210f12-502c-4d71-a098-4f595304a8d0",
"fields": [
{
"fieldId":"CPLastName",
"value":"Voornaam 2"
},
{
"fieldId": "CPFirstname",
"value": "Achternaam 2"
},
{
"fieldId":"OROrganisation",
"value":"Bedrijf 2"
}
]
}
Use a temporary helper variable in cases like this, that you assemble the array data structure for a single item in.
Add that temp array to the result array at the end of the outer loop.
$request = [];
foreach($address_data as $address) {
$temp = [];
foreach($address as $key => $value){
if($key == 'campaignId') {
$temp[$key] = $value;
}
if (strpos($key, 'fields') !== false) { // === 0 would perhaps make more sense here
$fields = explode('.', $key);
$temp['fields'][] = [
'fieldId' => $fields[1],
'value' => $value
];
}
}
$request[] = $temp;
}
echo json_encode($request);

Array to string conversion laravel 5.6

$data = $request->all();
if (!empty($data))
{
foreach ($data as $key => $value)
{
if($key === "_token")
{
continue;
}
$val = [
'questionnaire_id' => $questionnaire_id,
'question_id' => $key,
'answer' => $value
];
$answer = Answer::create($val);
}
}
This is my array
{
"_token": "URP1tlRfoD0RFMYIgVIyBX1AYaobDsQU2wnvxC1r",
"questionnaires_id": "5",
"questions": {
"2": "a",
"10": "3",
"11": "b",
"44": "2018-08-01"
}
}
this is my model class
class Answer extends Model
{
protected $fillable = [
'questionnaire_id', 'question_id', 'answer'
];
}
Change your code like this
$qs = $request->questions;
$qr = $request->questionnaires_id;
foreach ($qs as $k => $q)
{
$val = [
'questionnaire_id' => $qr,
'question_id' => $k,
'answer' => $q
];
$answer = Answer::create($val);
}
If you want to convert only array to string, You should use php function like json_encode()
To store array in DB/Model you can do this:
protected $casts = [
'answer' => 'array'
];
And $answer can be:
$answer = array($your_data);
You should follow this flow.
$data = $request->all();
if (!empty($data))
{
$questionnaires_id = 0;
$questions = [];
foreach ($data as $key => $value)
{
if($key === "_token")
{
continue;
}
if($key === "questionnaires_id")
{
$questionnaires_id = $value;
}
if($key === "questions")
{
$questions = $value;
}
}
foreach ($questions as $key => $value) {
$val = [
'questionnaire_id' => $questionnaires_id,
'question_id' => $key,
'answer' => $value
];
$answer = Answer::create($val);
}
}

How to get join table data and pass inside array in php

I have two tables order and orderDetail. i have multiple delivery address in order detail table based on id of order table
i want to display id from order table and deliveryAddress from order detail table.i am getting below output when i print..
but unable to display delivery_address.please anyone can suggest how i display delivery_address..
{
"responseData": {
"status": 1,
"message": "",
"result": [
{
"Order": {
"id": "677",
"detail_location_instructions": "Near Inox"
},
"OrderDetail": [
{
"order_id": "677",
"delivery_address": "Smart Club Gimnasio - Avenida Álvarez Thomas, Buenos Aires, Autonomous City of Buenos Aires, Argentina"
},
{
"order_id": "677",
"delivery_address": "Lower Fort Street, Dawes Point, New South Wales, Australia"
}
]
},
{
"Order": {
"id": "680"
},
"OrderDetail": []
},
{
"Order": {
"id": "684"
},
"OrderDetail": [
{
"order_id": "684",
"delivery_address": "Four Seasons - Posadas"
}
]
}
]
}
}
below is my code
public function getOrderlist(){
if($this->processRequest){
$err = false;
if(empty($this->requestData['id'])){
$this->responceData['message'] = "Please provide User ID";
$err = true;
}
if(!$err){
$id = trim($this->requestData['id']);
$conditions = array('Order.user_id'=>$id);
$data = $this->Order->find('all',array('conditions'=>$conditions));
if(!empty($data)){
$c = array();
foreach ($data as $key => $value) {
$c[] = array(
'Id' => $value['Order']['id'],
'deliveryAddress' => $value['OrderDetail']['delivery_address']
);
}
}
$this->responceData['result'] = $c;
$this->responceData['status'] = 1;
}
}
}
You have to put the deliveryAddress in array
$c = array();
foreach ($data as $key => $value) {
$myOrders = [
'Id'=>$value['Order']['id'],
'deliveryAddress'=>[]
];
foreach($value['OrderDetail'] as $address){
$myOrders['deliveryAddress'][] = $address['delivery_address'];
}
$c[] = $myOrders;
}
Hope this will help
can you trying below code.
foreach ($data as $key => $value) {
$c[] = array(
'Order' => array(
'id'=>$value['Order']['id'],
'detail_location_instructions' => $value['Order']['detail_location_instructions'],
),
'OrderDetail' => array(
'order_id'=>$value['Order']['id'],
'deliveryAddress' => $value['OrderDetail']['delivery_address'],
),
)
}
There is cases where you dont get the delivery address, in that case, you need to check if it exists first. use the Hash utility for that purpose.
I transformed the data to an array, in order for the class Hash to work.
public function getOrderlist(){
if($this->processRequest){
$err = false;
if(empty($this->requestData['id'])){
$this->responceData['message'] = "Please provide User ID";
$err = true;
}
if(!$err){
$id = trim($this->requestData['id']);
$conditions = array('Order.user_id'=>$id);
$data =(array) $this->Order->find('all',array('conditions'=>$conditions));
if(!empty($data)){
$c = array();
foreach ($data as $key => $value) {
$c[] = array(
'Id' => Hash::get($value, 'Order.id'),
'deliveryAddress' => current(Hash::extract($value, 'OrderDetail.{n}.delivery_address', array()))
);
}
}
$this->responceData['result'] = $c;
$this->responceData['status'] = 1;
}
}
}

Categories