I have a Laravel Collection of items:
[
[
'id' => 1,
'path' => '/',
'created_at' => '2020-05-20 20:12:00'
],
[
'id' => 2,
'path' => '/somewhere',
'created_at' => '2020-05-20 21:01:00'
],
[
'id' => 3,
'path' => '/somewhere',
'created_at' => '2020-05-20 21:21:00'
],
[
'id' => 4,
'path' => '/somewhere/else',
'created_at' => '2020-05-20 21:09:00'
],
[
'id' => 5,
'path' => '/somewhere/else',
'created_at' => '2020-05-20 21:10:00'
],
]
This is the raw data that would be found in the collection if I cast it to an array, but I need it to remain in collection format.
I need to remove any duplicates where the current item has the same path and is less than 5 minutes old compared to the previous item.
So in this case, item #4 would be removed leaving only #5, but items #2 and #3 would be kept even tho their paths are the same.
How would I do this?
Use the following namespace in your controller file:
use DateTime;
Use the following code in your controller file:
$collection = [
[
'id' => 1,
'path' => '/',
'created_at' => '2020-05-20 20:12:00'
],
[
'id' => 2,
'path' => '/somewhere',
'created_at' => '2020-05-20 21:01:00'
],
[
'id' => 3,
'path' => '/somewhere',
'created_at' => '2020-05-20 21:21:00'
],
[
'id' => 4,
'path' => '/somewhere/else',
'created_at' => '2020-05-20 21:09:00'
],
[
'id' => 5,
'path' => '/somewhere/else',
'created_at' => '2020-05-20 21:10:00'
],
];
$paths = [];
$time_count = [];
foreach ($collection as $key => $data) {
if (in_array($data['path'], $paths)) {
$arr_pos = array_search($data['path'], array_values($paths));
$datetime1 = new DateTime($data['created_at']);
$datetime2 = new DateTime($collection[$arr_pos]['created_at']);
$interval = $datetime1->diff($datetime2);
$mins = $interval->format('%i');
if ($mins < 5) {
unset($collection[$arr_pos]);
}
}
$paths[] = $data['path'];
}
This will return result:
array:4 [▼
0 => array:3 [▼
"id" => 1
"path" => "/"
"created_at" => "2020-05-20 20:12:00"
]
1 => array:3 [▼
"id" => 2
"path" => "/somewhere"
"created_at" => "2020-05-20 21:01:00"
]
2 => array:3 [▼
"id" => 3
"path" => "/somewhere"
"created_at" => "2020-05-20 21:21:00"
]
4 => array:3 [▼
"id" => 5
"path" => "/somewhere/else"
"created_at" => "2020-05-20 21:10:00"
]
]
I hope this works for you.
Related
I am self leaner and stuck at getting the sum of array which i am getting.
Ref. attached image showing the array.
for Month of Aug.
"Aug-2022" => array:6 [▼
"annualbuffalomilksalerecordforcustomer" => "8.00"
"annuala2milksalerecordforcustomer" => "5.50"
"annualjerseymilksalerecordforcustomer" => "2.50"
"annualbuffalomilksalerecord" => "168.00"
"annuala2milksalerecord" => "0.00"
"annualjerseymilksalerecord" => "390.00"
Here i want the sum all 6 which is = 574.00
expected result is -
"Aug-2022" => array:6 [▼
"annualbuffalomilksalerecordforcustomer" => "8.00"
"annuala2milksalerecordforcustomer" => "5.50"
"annualjerseymilksalerecordforcustomer" => "2.50"
"annualbuffalomilksalerecord" => "168.00"
"annuala2milksalerecord" => "0.00"
"annualjerseymilksalerecord" => "390.00"
"sumofmilksale" => "574.00"
You could do it like this using the map() function :
$collection = collect([
'Apr-2022' => [
"annualbuffalomilksalerecordforcustomer" => "8.00",
"annuala2milksalerecordforcustomer" => "5.50",
"annualjerseymilksalerecordforcustomer" => "2.50",
"annualbuffalomilksalerecord" => "168.00",
"annuala2milksalerecord" => "0.00",
"annualjerseymilksalerecord" => "390.00",
],
'May-2022' => [
"annualbuffalomilksalerecordforcustomer" => "8.00",
"annuala2milksalerecordforcustomer" => "5.50",
"annualjerseymilksalerecordforcustomer" => "2.50",
"annualbuffalomilksalerecord" => "168.00",
"annuala2milksalerecord" => "0.00",
"annualjerseymilksalerecord" => "390.00",
],
]);
$mapped = $collection->map(function ($entry) {
$sum = array_sum($entry);
return array_merge($entry, ['sumofmilksale' => $sum]);
})
dd($mapped);
I'm trying to create a kind of dataset using laravel Collections, for this I'm using the "times" method:
function getValidData(int $amount): Collection
{
return Collection::times($amount, function (int $number): array {
$password = faker()->password(8, 12);
return [
"User #{$number}" => [
'name' => faker()->firstName(),
'email' => faker()->unique()->safeEmail(),
'password' => $password,
'password_confirmation' => $password
]
];
});
}
However, the result is not as I expected:
[
0 => [
'User #1' => [
'name' => 'ana',
'email' => 'ana#email.com',
'password' => '12345678',
'password_confirmation' => '12345678'
]
],
1 => [
'User #2' => [
'name' => 'leo',
'email' => 'leo#email.com',
'password' => '3231232132',
'password_confirmation' => '3231232132'
]
]
]
I was hoping it would be:
[
'User #1' => [
'name' => 'ana',
'email' => 'ana#email.com',
'password' => '12345678',
'password_confirmation' => '12345678'
],
'User #2' => [
'name' => 'leo',
'email' => 'leo#email.com',
'password' => '3231232132',
'password_confirmation' => '3231232132'
]
]
I can solve this using array_merge(...(Collection::times...)) but it seems a kinda off... Is there any way to solve this in a cleaner way using Collections?
If you would like to map the collection with new keys, you could do the following, using the mapWithKeys() function.
Example
$users = collect(range(1, $amount))
->mapWithKeys( function($index) {
$password = faker()->password(8, 12);
return [sprintf("User #%d", $index) => [
'name' => faker()->firstName(),
'email' => faker()->unique()->safeEmail(),
'password' => $password,
'password_confirmation' => $password,
]];
});
This will run from 1 to the specified $amount. Example output with 3 users:
Illuminate\Support\Collection {#2016
#items: array:3 [
"User #1" => array:4 [
"name" => "Garret"
"email" => "aurelio03#example.com"
"password" => "Vp=Et3!?w0"
"password_confirmation" => "Vp=Et3!?w0"
]
"User #2" => array:4 [
"name" => "Genoveva"
"email" => "hilda.bins#example.net"
"password" => "W?miL1Kts"
"password_confirmation" => "W?miL1Kts"
]
"User #3" => array:4 [
"name" => "Zella"
"email" => "mmurray#example.net"
"password" => "g8)"pYgjQ~"
"password_confirmation" => "g8)"pYgjQ~"
]
]
}
You could also chain the toArray() method on the collection if you prefer an Array over a Collection.
I am working on eCommerce website where is stored all cart product in session that is working perfectly.
Here are debug of cart session.
debug($this->request->getsession()->read('cart'));
[
(int) 1 => [
(int) 0 => [
'id' => (int) 1,
'picture' => '1_1.webp',
'sku' => 'TH447WA38OUMINDFAS',
'name' => 'The Vanca Multicoloured Printed Strappy Top',
'size' => 'S',
'price' => '480'
]
],
(int) 2 => [
(int) 0 => [
'id' => (int) 2,
'picture' => '2_1.webp',
'sku' => 'AL384WA86QOSINDFAS',
'name' => 'All About You Pink Embroidered Blouse',
'size' => 'S',
'price' => '1330'
]
],
(int) 3 => [
(int) 0 => [
'id' => (int) 3,
'picture' => '3_1.webp',
'sku' => 'RE367WA35NDKINDFAS',
'name' => 'Renka Comfortable Black Color Seamless Summer Tops For Women',
'size' => 'S',
'price' => '495'
]
]
]
Now i want to remove any row from cart but that is not working for me.
unset($this->request->getsession()->read('cart')[1]);
should be simply
$this->request->getSession()->delete('cart.1');
you can use dot notation when accessing session arrays
you could also read and delete the data in one command
$cart = $this->request->getSession()->consume('cart');
see the manual here and the API here and here
I am trying to validate recursive data which could have any number of levels e.g.
[
'name' => 'test',
'children' => [
[
'name' => 'test2'
],
[
'name' => 'test3',
'children' => [
'name' => 'test4'
]
],
[
'name' => 'test5',
'children' => [
'name' => 'test6'
'children' => [
'name' => 'test7'
]
]
]
]
]
In this example I would require the following rules to ensure that a name is specified at each level:
$rules = [
'name' => ['required'],
'children' => ['array'],
'children.*.name' => ['required'],
'children.*.children' => ['array'],
'children.*.children.*.name' => ['required'],
'children.*.children.*.children' => ['array'],
'children.*.children.*.children.*.name' => ['required'],
]
How could I dynamically generate the validation rules based on the data coming in?
When I try to match one field in query everything works fine with highlighting in elasticsearch.
When I try to use:
$params = [
'index' => 'my_index',
'type' => 'articles',
'body' => [
'from' => '0',
'size' => '10',
'query' => [
'bool' => [
'must' => [
'match' => [ 'content' => 'what I want to search' ]
]
]
],
'highlight' => [
'pre_tags' => ['<mark>'],
'post_tags' => ['</mark>'],
'fields' => [
'content' => [ 'fragment_size' => 150, 'number_of_fragments' => 3 ]
]
],
]
];
everything works, but when I try to catch multiple fields, my search works correctly, but highlighting disappears.
'match' => [ 'content' => 'what I want to search' ],
'match' => [ 'type' => 1 ]
Do you know how to achieve functional highlighting, when I want apply search on two different fields with two different queries?
try this:
$params = [
'index' => 'my_index',
'type' => 'articles',
'body' => [
'from' => '0',
'size' => '10',
'query' => [
'bool' => [
'must' => [
'match' => [ 'content' => 'what I want to search' ]
]
],
'filter' => ['type' => 1]
]
] ],
'highlight' => [
'pre_tags' => ['<mark>'],
'post_tags' => ['</mark>'],
'fields' => [
'content' => [ 'fragment_size' => 150, 'number_of_fragments' => 3 ]
]
],
]