Is it possible to use $request->except on a nested array? This is the request data:
[▼
"id" => 1
"products" => array:1 [▼
0 => array:4 [▼
"id" => 1
"name" => "sample product"
"date" => "07/04/2022"
"frequency" => array:1 [ …1]
]
]
]
My goal is to remove some key value pairs e.g. removing id, date and frequency. My desired result would be:
[▼
"id" => 1
"products" => array:1 [▼
0 => array:1 [▼
"name" => "sample product"
]
]
]
What I've tried so far is to use Arr:except function:
$request->products = Arr::except($request->products['0'], ['id', 'date', 'frequency']);
But this should be applied on all items. Let's say I have two item products, the desired result would be:
[▼
"id" => 1
"products" => array:2 [▼
0 => array:1 [▼
"name" => "sample product"
]
1 => array:1 [▼
"name" => "sample product 2"
]
]
]
Need your inputs on what's the best approach for this. Thank you!
Unless I am missing something obvious, could you not just iterate over the products in your $request object?
$filtered = [];
foreach ($request->products as $product) {
$filtered[] = Arr::except($product, ['id', 'date', 'frequency']);
}
dd($filtered);
Resulting in $filtered containing:
^ array:2 [▼
"id" => 1
"products" => array:2 [▼
0 => array:1 [▼
"name" => "sample product"
]
1 => array:1 [▼
"name" => "sample product 2"
]
]
]
Update 1
I can see that the $request except only works on the top level
Not sure what you mean by this as the above principle works for me.
$filtered = [];
foreach ($request->products as $product) {
$filtered[] = Arr::except($product, ['id', 'date', 'frequency']);
}
$request->merge(['products' => $filtered]);
If I supply the above with the following:
{
"id": 1,
"products": [
{
"id": 1,
"name": "sample product",
"date": "07/04/2022",
"frequency": []
},
{
"id": 2,
"name": "sample product 2",
"date": "07/04/2022",
"frequency": []
}
]
}
Then do a dd($request->products); I get:
^ array:2 [▼
0 => array:1 [▼
"name" => "sample product"
]
1 => array:1 [▼
"name" => "sample product 2"
]
]
Related
I have the following array structure from a database query:
I extended my previous posts, with more details about the array structure. Hope that helps to better understand my example.
array:7 [▼
0 => array:4 [▼
0 => array:2 [▼
"my_first_key" => "option 1"
"SUMME" => "6"
]
1 => array:2 [▼
"my_first_key" => "option 2"
"SUMME" => "22"
]
2 => array:2 [▼
"my_first_key" => "option 3"
"SUMME" => "37"
]
3 => array:2 [▼
"my_first_key" => "option 4"
"SUMME" => "42"
]
],
0 => array:4 [▼
0 => array:2 [▼
"my_second_key" => "option 1"
"SUMME" => "6"
]
1 => array:2 [▼
"my_second_key" => "option 2"
"SUMME" => "22"
]
2 => array:2 [▼
"my_second_key" => "option 3"
"SUMME" => "37"
]
3 => array:2 [▼
"my_second_key" => "option 4"
"SUMME" => "42"
]
]
...
]
How can I transform it to a much simpler structure like:
array:8 [▼
"my_first_key" => array:4 [▼
"option 1" => "6"
"option 2" => "22"
"option 3" => "37"
"option 4" => "42"
],
"my_second_key" => array:4 [▼
"option 1" => "6"
"option 2" => "22"
"option 3" => "37"
"option 4" => "42"
]
...
]
I tried to give array_walk_recursive a try, but I can't grab the SUMME key and bind it to the previous option?
$tmpArr = [];
array_walk_recursive($data, static function ($value, $key) use (&$tmpArr) {
$tmpArr[$key][$value] = $value; // not $value? SUMME here?
}, $tmpArr);
You need to simple do it like below using foreach()
$tmpArr = [];
foreach($data as $dat){
foreach($dat as $d){
$key = array_keys($d)[0];
$tmpArr[$key][$d[$key]] = $d['SUMME'];
}
}
Output : https://3v4l.org/hmu5r
If you want to use array_walk_recursive you can do it like this:
$output = [];
array_walk_recursive($arr, function ($item, $key) use (&$output) {
if ($key === 'SUMME') {
end($output);
$a = key($output);
end($output[$a]);
$b = key($output[$a]);
$output[$a][$b] = $item;
} else {
$output[$key][$item] = '';
}
});
I have a collection of restaurants and I want to query them with two diffrent criterias and merge them together
I have two aggregation pipelines one that is a $match and the other one that is a $geoNear ,
array:1 [▼
0 => array:1 [▼
"$match" => array:1 [▼
"$or" => array:1 [▼
0 => array:1 [▼
"$and" => array:2 [▼
0 => array:1 [▼
"country" => array:1 [▶]
]
1 => array:1 [▼
"$or" => array:1 [▼
0 => array:1 [▼
"$or" => array:1 [▶]
]
]
]
]
]
]
]
and
^ array:1 [▼
0 => array:1 [▼
"$geoNear" => array:5 [▼
"near" => array:2 [▶]
"distanceField" => "distance.calculated"
"spherical" => true
"key" => "location"
"query" => array:1 [▶]
]
]
]
I want to be able to make just one call/ in one pipeline and get ALL NON DUPLICATES restaurants. (a way to identify them it would be with the _id )
For example getting all the ones that match $match pipeline , the same with $geoNear , merge them and remove duplicates
You can use query option in $geoNear. It will include the documents which matches the condition in query.
Reference
Sample from documentation:
db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "dist.calculated",
maxDistance: 2,
query: { category: "Parks" }, //Query portion
includeLocs: "dist.location",
spherical: true
}
}
])
This is my sample array value returned
array:3 [▼
"Status" => array:1 [▼
0 => "200"
]
"Data" => array:1 [▼
0 => array:1 [▼
0 => array:2 [▼
"sellerId" => array:1 [▼
0 => "TEST01"
]
"currency" => array:1 [▼
0 => "USD"
]
]
]
]
"Date" => array:1 [▼
0 => "Dec 31 2019"
]
]
My sample code to retrieve the value from the array above
foreach($json_array as $key => $json) {
if($key == "Status") {
$status = $json[0];
} else if ($key == "Date") {
$date = $json[0];
} else {
dd($json[0][0]['sellerId'][0]);
}
}
I am using the method above to retrieve the value from multidimensional array. Is there any better approaches that i can use to achieve my way?
Just do :
$status = $json_array['Status'];
$date = $json_array['Date'];
Maybe you should add some context to your question.
I have an array with some data that returns me from the database, the problem is that not all the keys are associated, I should fill the missing keys with data to 0.
My array is by default is:
array:1 [▼
9 => array:2 [▼
4 => array:3 [▼
"Orange" => array:3 [▼
"price" => "600.00"
"total" => "690.00"
]
"Apple" => array:3 [▼
"price" => "650.00"
"total" => "870.00"
]
"Banana" => array:3 [▼
"price" => "50"
"total" => "40"
]
]
21 => array:1 [▼
"Apple" => array:3 [▼
"price" => "44"
"total" => "33"
]
]
]
]
The array should have the same structure but with data at 0
Result:
array:1 [▼
9 => array:2 [▼
4 => array:3 [▼
"Orange" => array:2 [▼
"price" => "600.00"
"total" => "690.00"
]
"Apple" => array:2 [▼
"price" => "650.00"
"total" => "870.00"
]
"Banana" => array:2 [▼
"price" => "50"
"total" => "40"
]
]
21 => array:3 [▼
"Apple" => array:2 [▼
"price" => "44"
"total" => "33"
],
"Orange" => array:2 [▼
"price" => "0"
"total" => "0"
],
"Banana" => array:2 [▼
"price" => "0"
"total" => "0"
]
]
]
]
The "for" below modify each array with adding any new value and also avoid duplicate values. Basically, it finds the differences and then merge that, setting the first array to clone each array.
$fruits = array (
1 => array('Manzana', 'Naranja', 'Pera'),
2 => array('Pera', 'Sandia'),
3 => array('Manzana', 'Melocotones')
);
print_r($fruits);
for ($i = 1; $i <= count($fruits)-1; $i++) {
$result = array_diff($fruits[1], $fruits[1+$i]);
$merge = array_merge($fruits[1+$i], $result);
$fruits[1+$i] = $merge;
$fruits[1] = $merge;
}
print_r($fruits);
?>
Here to see how run it!
https://repl.it/KqUi/3
If you will always use the first element as boilerplate you can do something like this:
$boilerplate = reset($array);
array_walk_recursive($boilerplate, function (&$value) {
$value = 0;
});
$array = array_map(function ($items) use ($boilerplate) {
return array_merge($items, array_diff_key($boilerplate, $items));
}, $array);
Here is working demo.
I have a php array something like this:
array:7 [▼
"id" => 13
"agent_id" => 1
"reserved_by" => 1
"vehicle_type" => "["Bus","Car"]"
"no_of_vehicle" => "["2","1"]"
"created_at" => "2017-06-13 05:46:49"
"updated_at" => "2017-06-13 05:46:49"
]
Here, vehicle_type and no_of_vehicle are in json_encode format. In the above case,
By json_decode I can get two arrays like this
vehicle_type
dd(json_decode($data->vehicle_type));
array:2 [▼
0 => "Bus"
1 => "Car"
]
no_of_vehicle
dd(json_decode($data->no_of_vehicle));
array:2 [▼
0 => "2"
1 => "1"
]
Now, what I want is to create an associative array of vehicle type and number equals 1.
array:3 [▼
Bus => "1"
Bus => "1"
Car => "1"
]
It's impossible as all you say because of unique key. But, Is to possible to make similar array with nested like:
array:3 [▼
array:1 [▼
Bus => "1"
]
array:1 [▼
Bus => "1"
]
array:1 [▼
Bus => "1"
]
]
That will be fine for me
Any idea, I am using laravel 5.3
Thanks
array:3 [▼
Bus => "1"
Bus => "1"
Car => "1"
]
It's impossible, because the keys must unique
you can make it to
["Bus", "Bus", "Car"]
or
["Bus" => 2, "Car" => 1]
Answer to updated question
You can do like this:
$array = [
"id" => 13,
"agent_id" => 1,
"reserved_by" => 1,
"vehicle_type" => array("Bus", "Car"),
"no_of_vehicle" => array("2", "1"),
"created_at" => "2017-06-13 05:46:49",
"updated_at" => "2017-06-13 05:46:49",
];
$result = [];
foreach ($array["vehicle_type"] as $key => $vehicle) {
$num = intval($array["no_of_vehicle"][$key]);
for ($i = 1; $i <= $num; $i++) {
$result[] = array($vehicle => "1");
}
}
the $result will be:
array:3 [▼
0 => array:1 [▼
"Bus" => "1"
]
1 => array:1 [▼
"Bus" => "1"
]
2 => array:1 [▼
"Car" => "1"
]
]
I would create an array like that :
array[
{
vehicle_type => 'Bus',
no_of_vehicle => 2,
},
{
vehicle_type => 'Car',
no_of_vehicle => 1,
}
]
or
array['Bus_1', 'Bus_2', 'Car_1']