Pluck id (integer) cast to string Laravel - php

While plucking from a database, I get id as strings.
$alphabets = new Alphabet();
return $alphabets->pluck('name', 'id');
Output
{
"1": "Apple",
"2": "Ball",
"3": "Cat"
}
Expected
{
1: "Apple",
2: "Ball",
3: "Cat"
}
But, when I reverse ID and name,
return $alphabets->pluck('id', 'name');
I get id as integer.
{
"Apple": 1,
"Ball": 2,
"Cat": 3
}
I'm not sure what's happening behind the scene. But how can I get ID in integer ? Actually, old flash session doesn't set value because of 1 vs "1" in Form Collective.
{!! Form::select('alphabet', $alphabets, null, ['class' => 'form-control', 'multiple' => true]) !!}

Try this code
$alphabets = new Alphabet();
return $alphabets->all()->pluck('name', 'id');
Alphabet.php
You should cast your columns like this.
protected $casts = [
'id' => 'integer',
'name' => 'string'
];

I think I found the answer here.
https://laracasts.com/discuss/channels/laravel/pluck-id-integer-cast-to-string
Here I found JSON only allows key names to be strings.
Using number as "index" (JSON)
{
"1": "Apple",
"2": "Ball",
"3": "Cat"
}
Actually, I want to achieve it for Form Collective. It was a bug and it's PR has been merged now.
https://github.com/LaravelCollective/html/pull/368#pullrequestreview-46820423

you also convert key into int
$alphabets = new Alphabet();
$alphaArr =$alphabets->pluck('name', 'id');
foreach($array as $key => $value) {
$newArray[(int) $key] = $value;
}

Usually, pluck() method gives you associative array of values
in string values.
So, try using select statements like this:
$data = Alphabet::select('id','name')->get()->toArray();
This will give you following result:
array:3 [▼
0 => array:2 [▼
"id" => 1
"name" => "Apple"
]
1 => array:2 [▼
"id" => 2
"name" => "Ball"
]
2 => array:2 [▼
"id" => 3
"name" => "Cat"
]
]
Now, using simple loop you can get your expected array.
$expected = array();
foreach($data as $d){
$expected[$d['name']] = $d['id'];
}
dd($expected);

Adding this line fix the old session issue of LaravelCollective/Html.
|| in_array((string) $value, $selected, true)
/**
* Determine if the value is selected.
*
* #param string $value
* #param string $selected
*
* #return null|string
*/
protected function getSelectedValue($value, $selected)
{
if (is_array($selected)) {
return in_array($value, $selected, true) || in_array((string) $value, $selected, true) ? 'selected' : null;
} elseif ($selected instanceof Collection) {
return $selected->contains($value) ? 'selected' : null;
}
return ((string) $value == (string) $selected) ? 'selected' : null;
}

Related

Check if value is in array using 2 specific keys

I have an array like this:
$arr = ({
"ID":"10",
"date":"04\/22\/20"
},
{
"ID":"20",
"date":"05\/25\/20"
},
{
"ID":"32",
"date":"07\/13\/20"
});
I want to know if values on 2 different keys exist in the array, how can I Achieve that?
Example: if id is equal to 32 and date equals to 07/13/20, return true.
I've tried in_array($monthName, array_column($GLOBALS['group_posts_array'], 'month')); but this only works on one key. I want to achieve to keys at once, kind of like && in if statement.
I don't think $arr in the question is a valid php array, but if it should be a multidimensional array, you might also pass for example an array to in_array with the keys and values that you are looking for:
$arr = [
[
"ID" => "10",
"date" => "04\/22\/20"
],
[
"ID" => "20",
"date" => "05\/25\/20"
],
[
"ID" => "32",
"date" => "07\/13\/20"
]
];
$values = [
"ID" => "32",
"date" => "07\/13\/20"
];
var_dump(in_array($values, $arr, true));
$values["ID"] = "33";
var_dump(in_array($values, $arr, true));
Output
bool(true)
bool(false)
You can implement a 'some' function.
function some(array $arr, callable $fn):bool{
foreach($arr as $index=>$item){
if($fn($item, $index)){
return true;
}
}
return false;
}
The usage would be something like the following:
$id = 32;
$date = "07/13/20";
$isInArray = some($arr, function($item, $index) use ($id, $date){
return $item->id == $id && $item->date == $date;
})

Laravel PHP move collection item to the top of the collections

This is just in case someone else has the same question and like me did not find a suitable answer to solve it.
I had a collection that had to be filtered so the active item comes first on the collections when a certain value was passed.
Illuminate\Database\Eloquent\Collection {
0 => array:2 [
"id" => 1
"name" => "Bogan, Weissnat and Jenkins"
]
1 => array:2 [
"id" => 4
"name" => "Grady-Barrows"
]
2 => array:2 [
"id" => 7
"name" => "Howe and Sons"
]
3 => array:2 [
"id" => 3
"name" => "Macejkovic-Altenwerth"
]
]
}
Needed to move an item top based on the id which is passed by URL
$activeId = 3; // Your active item id
$collection = $collection
->sortBy('id')
->sortBy(fn($item) => $item->id !== $activeId);
This will sort your collection by id and move a specific item to the top.
(PHP7.4+ for arrow function)
You can simply sort the collection by a custom function:
use Illuminate\Support\Collection;
$data = collect([
["id" => 1, "name" => "Bogan, Weissnat and Jenkins"],
["id" => 4, "name" => "Grady-Barrows"],
["id" => 7, "name" => "Howe and Sons"],
["id" => 3, "name" => "Macejkovic-Altenwerth"],
]);
$key = "name";
$value = "Grady-Barrows";
public function moveFirst(Collection $data, string $key, mixed $value): Collection
{
return $data->sortBy(fn($v) => $v[$key] !== $value);
}
It will return false (0) for the matching entry and true (1) for the rest, so the matching entry gets put on top. Using arrow functions makes for a much simpler syntax.
This is how I did solve it.
public function moveOtherToTop($collection, $key, $item)
{
return $collection->reject(function ($value) use ($item){
return $value[$key] == $item;
})->prepend($collection->filter(function ($value) use ($item) {
return $value[$key] == $item;
})[$item]);
}
Idea came out from Laracast and Stillat article.
In case there is a better solution to this answer am open to suggestions.
I run this in Laravel 5.8
use Illuminate\Support\Collection;
function moveItemToTopCollection(Collection $collection, String $key, $value) :Collection
{
$item_to_first = null;
// Search element to top
foreach ($collection as $item) {
if ($item->$key == $value){
$item_to_first = $item;
break;
}
}
// If element not found, return original collection
if (!$item_to_first){
return $collection;
}
// Element to top, first remove of collection, then insert to top
return $collection->reject(function ($value) use ($item_to_first){
return $value == $item_to_first;
})->prepend($item_to_first);
}
You can use the prioritize method from the great spatie/laravel-collection-macros package.

how to insert a nested 2d array in database in laravel using realtionship

I am trying to save the Home model with its realation ship called Phone that I want to insert unlimited Phones for it . Now I am inserting home without any problem but when it comes to phone I can't insert my 2d array into phone ! Here is my controller :
$validated = $request->all();
if (!$validated) {
return $this->sendError('Validation Error.', $validated->errors());
}
$home = Home::create($validated);
$phones = $request->input('phones');
for ($i =0; $i < count($phones); $i++) {
$insertPhone[$i] = json_decode($phones[$i]);
}
dd($insertPhone);
$home->phones()->createMany($insertPhone);
return new HomeResource($home);
and down there is the dd result of $insertPhone :
array:2 [
0 => {#533
+"value": "123"
+"is_attachment": "true"
}
1 => {#538
+"value": "456"
+"is_attachment": "true"
}
]
createMany expects a multidimensional array with key / value, for example :
$home->phones()->createMany([
[
'number' => '049230323432',
],
[
'number' => '432094249023',
],
]);
So you should do like :
$phones = $request->input('phones');
$insertPhone = [];
foreach ($phones as $phone) {
$insertPhone []= [
'number' => $phone,
];
}

Returning elements from an array nest based on criteria

I am trying to search an array for an element (in this case 'electronic'), then return the nested value.
The array that I am working with
array:2 [▼
0 => array:2 [▼
"value" => "0241-6230"
"type" => "print"
]
1 => array:2 [▼
"value" => "2339-1623"
"type" => "electronic"
]
]
Below is the code I'm using.
<?php
$this->doi = 'anydoinumber';
$this->client = new Client();
$this->Url = 'https://api.crossref.org/works/:'.$this->doi;
$res = $this->client->get($this->Url);
$decoded_items = json_decode($res->getBody(), true);
if (isset($decoded_items['message']['issn-type'])) {
$this->issn = '';
} else {
// no electronic ISSN given
Log.Alert('No electronic ISSN for :'.$this->Doi);
}
The output I'm expecting
$this->issn = "2339-1623"
You can use laravel collection:
collect($array)->where('type', 'electronic')->first();
And output is:
array:2 [
"value" => "2339-1623"
"type" => "electronic"
]
You could use a simple foreach loop that adds matching elements to a results array
$filtered = [];
foreach($myarr as $i){
if($i['type'] == 'searched type')
$filtered[] = $i;
}
or you can break out of the loop when you encounter first element of given type
foreach($myarr as $i){
if($i['type'] == 'searched type')
return $i; // or $found = $i and then break;
}
PHP way:
$searchingFor = 'electronic';
$filteredArray = array_filter($initialArray, function($v, $k) use ($searchingFor) {
return $searchingFor === $v['type'];
}, ARRAY_FILTER_USE_BOTH);
//var_dump($filteredArray);
Docs.
You Have To user foreach loop
$searchterm = 'electronics';
foreach($nested as $key => $value) {
if($value['type'] == $searchterm) {
return $value['value'];
break;
}
}

How to add different condition using json decode

$firstArray= [
[
"ID" => "ABC"
],
[
"ID" => "100"
],
[
"ID" => "200"
]
];
$firstArray= ["ABC" =>"fail"];
**Here I have to check two condition**
Condition #1
$abc i am having 3 values, out of this values suppose present in $second array,we have ignore the value and remaining only one value we have to assign $existarray
As of now i have completed it is working fine also,
Condition #2
I have one more json like this
$jsonString = '{
"jsonData" : {
"ABC" : {
"Count" :1
},
"100" : {
"Count" :3
},
"200" : {
"Count" :1
}
}
}';
$finalcount= json_decode($jsonString);
Now i want to check one more condition $abc array of mainarray key values count <10 we should ignore.This condition i have to implement my current code
Expected output
Array
(
[ID] => 200
)
Merging 2 condition in if statement is done with &&.
You can just mix those 2 condition in 1 for-loop:
$jsonString = '{"jsonData" : {
"ABC" : {"Count" :1},
"100" : {"Count" :3},
"200" : {"Count" :1}
}
}';
$firstArray = json_decode($jsonString, true);
$hobbies= [["ID" => "ABC"],["ID" => "100"],["ID" => "200"]];
$books= ["ABC" => true];
foreach ($Response as $key => $value) {
$id = $value['ID'];
if (!isset($books[$id]) && $firstArray["jsonData"][$id]["Count"] < 3 ) {
$selectedItem = $value;
break;
}
}

Categories