I have a collection which contains these values
'sales marketing|telemarketing',
what I'm trying to do is query/filter the items in collection but just based on the individual type so the for example value of 'telemarketing'. I have tried
$results = $data->where('Department', 'contains', $type); and also tried LIKE but because of the format with the pipe it's not picking the type/value.
This might be a dumb question but any ideas would be great!
The where-method also can handle only two Parameters. For example:
$data= collect([
['Department' => 'sales', 'price' => 200],
['Department' => 'marketing', 'price' => 100],
['Department' => 'telemarketing', 'price' => 150],
['Department' => 'marketing', 'price' => 100],
]);
$departmentName = "marketing";
$results = $data->where('Department', $departmentName);
dd($results);
Given your example:
[
"Employee" => "Some Company",
"Name" => "John Something",
"Usages" => "sales marketing|telemarketing",
"StartDate" => "1st Mar 2021",
"EndDate" => ""
]
The main issue is that the "Usage" property is a string containing multiple values, with the pipe character acting as a separator.
One solution to filter by one of those values is by mapping your original collection to transform the string in an array with the explode method and then use the filter method to filter based on the Usages you're interested in.
The resulting code might look like this:
$mappedCollection = $collection->map(function($el) {
$el['Usages'] = explode('|', $el['Usages']); // Transform the string into an array
return $el;
});
$result = $mappedCollection->filter(function($el) {
return in_array('sales marketing',$el['Usages']); // Change 'sales marketing' with the desired Usage
});
Related
I have a Laravel collection like this (approximating using array syntax; the actual data is a Collection of objects obtained from an API response, not a local DB):
$rows = [
[
'id': 1,
'name': 'Sue',
'age': 23,
],
[
'id': 2,
'name': 'Joe',
'age': 25,
],
]
I want to extract a subset of the fields:
$subset = [];
foreach ($rows as $row) {
$subset[] = ['name' => $row['name'], 'age' => $row['age']];
}
So that I end up with:
$subset = [
[
'name': 'Sue',
'age': 23,
],
[
'name': 'Joe',
'age': 25,
],
]
What Collection method should I use to achieve that instead of the for loop?
I found this suggestion, using a higher-order message, which made some kind of sense:
$subset = $rows->map->only(['name', 'age']);
but that just gives me a Collection of null values. Expanding it into a conventional map call produced the same effect. I feel like I want some kind of multipluck, but I'm not sure what that corresponds to!
Update
It turns out that I was doing this correctly with the higher-order map->only approach. However, while the items in my collection were a kind of Model, they were not a subclass or compatible implementation of the Laravel Model class, and lacked an implementation of the only method. The author added the method, and now it works as expected.
You were close, but you don't chain map and only, and only doesn't seem to work on a Collection of nested arrays/objects.
So, for your case, use map() with a Callback:
$rows = collect([
(object)[
'id' => 1,
'name' => 'Sue',
'age' => 23,
],
(object)[
'id' => 2,
'name' => 'Joe',
'age' => 25,
]
]);
$mapped = $rows->map(function ($row) {
return ['age' => $row->age, 'name' => $row->name];
});
dd($mapped->toArray());
Output of that would be:
array:2 [▼
0 => array:2 [▼
"age" => 23
"name" => "Sue"
]
1 => array:2 [▼
"age" => 25
"name" => "Joe"
]
]
Note: If these are arrays and not objects, then you'd do $row['age'] and $row['name'] instead of $row->age and $row->name. In Laravel, Models are both, and allow either syntax.
References:
https://laravel.com/docs/9.x/collections#method-map
https://laravel.com/docs/9.x/collections#method-only
Edit:
Some alternatives. If you have a Collection of Models, then you can natively do:
$mapped = $rows->map(function ($model) {
return $model->only(['age', 'name']);
});
If you have a Collection of Collections, then you can do:
$mapped = $rows->map(function ($collection) {
return $collection->only(['age', 'name']);
});
And lastly, if you arrays or objects, you can collect() and call ->only():
$mapped = $rows->map(function ($row) {
return collect($row)->only(['age', 'name']);
});
I got this:
$arr = json_decode($arr, TRUE);
while($row){
// $arr[] = ['id' => '8', 'name' => 'mickey'];
$test = $row->TCI_LIBELLE;
$arr[] = ['id' => $row->TCI_ID, 'name' => $row->TCI_LIBELLE];
$i +=1;
$row = $reqCentreInteret->fetch(PDO::FETCH_OBJ);
$json = json_encode($arr);
If you don't understand I'm trying to put values I get from a Select SQL query into a JSON array.
The problem is that it does't work like I want.
Indeed it works with my id because in my database it's an int value, but it does't work for the name because it is a varchar value
This is what i want to obtain :
[{"id":"8","name":"mickey"},{"id":"8","name":"mickey"}]
And here 'mickey' will be replaced by the value of my php string that will be initialized by my sql query
I already tried to solve my problem using
'name' => '" .$row->TCI_LIBELLE."'
But it does't work
How can I pass string value (or other type) to my JSON array?
I'm using PHP and JSON to send value from MySQL to an Android app.
arr[] = adds a new row to the array, i.e. a new top-level element.
You probably want to add your data to the existing element
Let's say your arr initially is something like
[ 'property1' => 'value1',
'property2' => 'value2'
...]
when you're doing
arr[] = ['id'=> 8,'name' => 'mickey']
your array will now contain 2 top level elements and look like
[[ 'property1' => 'value1',
'property2' => 'value2'
...
],
[ 'id' => 8,
'name' => 'mickey'
]
]
you may want to do this instead
arr['id'] = $row->TCI_ID;
arr['name'] = $row->TCI_LIBELLE;
then your arr will look like this:
[ 'property1' => 'value1',
'property2' => 'value2'
'id' => 8
'name' => 'mickey'
...
]
Finally this is what is had to do
$stmt = $db->query("SELECT TCI_ID AS id, TCI_LIBELLE AS nom FROM
OSO_DEV.T_CENTRE_INTERET");
echo json_encode($stmt->fetchAll(PDO:: FETCH_ASSOC),JSON_UNESCAPED_UNICODE);
I'm trying to print my collection sorted alphabeticall. Here's what I've tried inside my controller:
public function listForCategories(Category $category)
{
return $category->subcategories->sortBy('title');
}
But It's not sorting my output :/ Please help!
$category->subcategories->sortBy('title')->values()->all();
I don't know exact hierarchy but you can use the solution as per your needs:
The sortBy method sorts the collection by the given key. The sorted collection keeps the original array keys,
so in this example, we'll use the values method to reset the keys to consecutively numbered indexes:
Here is an example :
$category = collect([
['title' => 'Desk', 'price' => 200],
['title' => 'Chair', 'price' => 100],
['title' => 'Bookcase', 'price' => 150],
]);
$sorted = $category->sortBy('title')->values()->all();
Result-:
[
['title' => 'Bookcase', 'price' => 150],
['title' => 'Chair', 'price' => 100],
['title' => 'Desk', 'price' => 200],
]
try return $category->subcategories->orderBy('title');
The sortBy method sorts the internal fields, however, it preserves the original keys, therefore, if you want to have the sorted values, you should call the values() method after you've sorted the collection. That way you get the sorted collection back.
return $category->subcategories->sortBy('title')->values()->all();
Try using orderBy when you retrieve them from the database (I'm assuming you do)
public function listForCategories(Category $category)
{
return $category->subcategories()->orderBy('title')->get();
}
Im retrieving data from a mysql database like following Array:
$data = [
0 => [
'id' => 1,
'Benutzer' => 'foo',
'Passwort' => '123456',
'Adresse' => [
'Strasse' => 'bla', 'Ort' => 'blubb'
],
'Kommentare' => [
0 => ['Titel' => 'bar', 'Text' => 'This is great dude!'],
1 => ['Titel' => 'baz', 'Text' => 'Wow, awesome!']
]
],
]
Data like this shall be stored in a mongo database and therefore i want to replace the keynames with translated strings that come from a config- or languagefile ('Benutzer' -> 'username').
Do i really have to iterate over the array and replace the keys or is the a better way to achieve that?
If you don't want to iterate over the array then you can change the column name in the query itself using select() function.
Considering your model name is Client then your query will be:
Client::select('Benutzer as username', '...') // you can use `trnas()` function here also
->get()
I have MongoDB collection of documents containing several fields. One of the columns/fields should be numeric only, but some of these fields contain non-numerical (corrupt) data as string values. I should find the highest numerical value of this column, excluding the corrupt, non-numerical data. I am aware of the question Getting the highest value of a column in MongoDB, but AFAIK, this extended case was not covered.
The example below depicts the issue. For the highest value, the document with "age": 70 should be returned:
[
{
"id": "aa001",
"age": "90"
},
{
"id": "bb002",
"age": 70
},
{
"id": "cc003",
"age": 20,
}
]
Providing a PHP example for the find() / findOne() query would be of much help. Thanks a lot!
JohnnyHK came up with the perfect solution. Here's the working PHP code:
$cursor = $collection->find(array('age' => array('$not' => array('$type' => 2))), array('age' => 1));
$cursor->sort(array('age' => -1))->limit(1);
You can use the $type operator with $not in your query to exclude docs where age is a string. In the shell your query would look like:
db.test.find({age: {$not: {$type: 2}}}).sort({age: -1}).limit(1)
Or in PHP from Martti:
$cursor = $collection->find(array('age' => array('$not' => array('$type' => 2))), array('age' => 1));
$cursor->sort(array('price' => -1))->limit(1);
with PHP driver (mongodb)
using findOne()
$filter=[];
$options = ['sort' => ['age' => -1]]; // -1 is for DESC
$result = $collection->findOne(filter, $options);
$maxAge = $result['age']
You can use aggregate function to get maximum number from collections like this.
$data=$collection->aggregate(array
( '$group'=>
array('_id'=>'',
'age'=>array('$max'=>'$age'.)
)
)
);
This works for me
$options = ['limit' => 100,'skip' => 0, 'projection' => ['score' => ['$meta' => 'textScore']], 'sort' => ['score' => ['$meta' => 'textScore']]];