Laravel Multidimensional Array to Collection Object Values - arrays

I have an array that I'm wanting to recursively turn into a collection and to use the collection as object values.
I would like to use the collection object in similar ways that eloquent is used rather than using $contact['name'] and being able to use $collection->contacts->each vs foreach $collection->contacts .....)
$collection->contacts->each(function ($contact) {
// ability to use $contact->name (and not have to use $contact['name'])
});
Collection Macro:
Collection::macro('recursive', function () {
return $this->map(function ($value) {
if (is_array($value)) {
return (object)$value;
}
if (is_object($value)) {
return collect($value)->recursive();
}
return $value;
});
});
Example:
public function test_it_can_recursively_convert_array_to_collection()
{
$data = [
[
'name' => 'Michael Scott',
'emails' => [
'mscott#dundermifflin.com',
'michaelscarn#dundermifflin.com',
],
'contacts' => [
[
'name' => 'Dwight Schrute',
'emails' => [
'dschrute#dundermifflin.com',
],
],
[
'name' => 'Jim Halpert',
'emails' => [
'jhalpert#dundermifflin.com',
],
],
],
],
];
$collection = collect($data)->recursive();
$this->assertInstanceOf(Collection::class, $collection);
$collection->each(function ($item) {
$this->assertEquals('Michael Scott', $item->name);
$item->contacts->each(function ($contact) {
$this->assertNotNull($contact->name);
});
});
}
The original collection map works (e.g. $collection->each .... $item->name) but I can't seem to set convert the nested arrays to objects and get the object values.
Error: Call to a member function each() on array
Illuminate\Support\Collection^ {#632
#items: array:1 [
0 => {#13
+"name": "Michael Scott"
+"emails": array:2 [
0 => "mscott#dundermifflin.com"
1 => "michaelscarn#dundermifflin.com"
]
+"contacts": array:2 [
0 => array:2 [
"name" => "Dwight Schrute"
"emails" => array:1 [
0 => "dschrute#dundermifflin.com"
]
]
1 => array:2 [
"name" => "Jim Halpert"
"emails" => array:1 [
0 => "jhalpert#dundermifflin.com"
]
]
]
}
]
}

Related

Nested array validation rules not working on update in laravel

I have an array like this
"fio" => "John Dou"
"city" => "1"
"birthday" => "2022-10-21"
"email" => "test#gmail.ru"
"phones" => array:2 [▼
0 => array:2 [▼
"id" => "7"
"number" => "911"
]
1 => array:2 [▼
"id" => "10"
"number" => "112"
]
]
The check for uniqueness works, but when you try to update the current record, it swears for duplication
public function rules()
{
return [
'phones.*.number' => 'required|string|max:12|unique:'.Phone::class.',number,phones.*.id';
]
}
Maybe I made a mistake somewhere?

Using validated method with array in Laravel

This is the rquest body:
{
"arr": [
{
"a": 3,
"b": 3
},
{
"a": 3,
"b": 3
}
]
}
and with this validations rules:
public function rules()
{
return [
// 'arr' => 'array',
'arr.*.a' => 'required'
];
}
The result of dd($request->validated()); is what I want, I don't need b to be included
"arr" => array:2 [
0 => array:1 [
"a" => 3
]
1 => array:1 [
"a" => 3
]
]
But when I want to validate the array itself like this:
public function rules()
{
return [
'arr' => 'array',
'arr.*.a' => 'required'
];
}
b will be added to the output
"arr" => array:2 [
0 => array:1 [
"a" => 3,
"b" => 3
]
1 => array:1 [
"a" => 3,
"b" => 3
]
]
How can I prevent adding b to the dd($request->validated()); while validating the array itself?

Perl: How to iterate over arrays in multiple objects and extract values from webservice

I request a web service and get a JSON response:
{
"timestamp" : "2019-06-11T08:04:35Z",
"version" : "0.5",
"document" : [
{
"href" : "http://opac.sub.uni-goettingen.de/DB=1/PPNSET?PPN=1629107239",
"item" : [
{
"href" : "http://opac.sub.uni-goettingen.de/DB=1/PPNSET?PPN=1629107239",
"label" : "40 623 a",
"id" : "http://uri.gbv.de/document/opac-de-7:epn:3421084610",
"available" : [
{
"service" : "presentation"
}
],
"unavailable" : [
{
"service" : "loan"
},
{
"service" : "interloan"
}
]
},
{
"href" : "http://opac.sub.uni-goettingen.de/DB=1/PPNSET?PPN=1629107239",
"label" : "40 623 b",
"id" : "http://uri.gbv.de/document/opac-de-7:epn:342108467X",
"available" : [
{
"service" : "presentation"
}
],
"unavailable" : [
{
"service" : "loan"
},
{
"service" : "interloan"
}
]
}
],
"id" : "http://uri.gbv.de/document/opac-de-7:ppn:1629107239"
}
],
"institution" : {
"href" : "http://www.sub.uni-goettingen.de",
"content" : "Niedersächsische Staats- und Universitätsbibliothek Göttingen",
"id" : "http://uri.gbv.de/organization/isil/DE-7"
}
}
Then I parse the JSON with Perls Dumper::Data module:
my $data = decode_json($resultJson);
print Dumper($data);
It looks like:
$VAR1 = {
'document' => [
{
'item' => [
{
'available' => [
{
'service' => 'presentation'
}
],
'id' => 'http://uri.gbv.de/document/opac-de-7:epn:3421084610',
'href' => 'http://opac.sub.uni-goettingen.de/DB=1/PPNSET?PPN=1629107239',
'label' => '40 623 a',
'unavailable' => [
{
'service' => 'loan'
},
{
'service' => 'interloan'
}
]
},
{
'available' => [
{
'service' => 'presentation'
}
],
'unavailable' => [
{
'service' => 'loan'
},
{
'service' => 'interloan'
}
],
'id' => 'http://uri.gbv.de/document/opac-de-7:epn:342108467X',
'label' => '40 623 b',
'href' => 'http://opac.sub.uni-goettingen.de/DB=1/PPNSET?PPN=1629107239'
}
],
'id' => 'http://uri.gbv.de/document/opac-de-7:ppn:1629107239',
'href' => 'http://opac.sub.uni-goettingen.de/DB=1/PPNSET?PPN=1629107239'
}
],
'institution' => {
'content' => "Nieders\x{e4}chsische Staats- und Universit\x{e4}tsbibliothek G\x{f6}ttingen",
'id' => 'http://uri.gbv.de/organization/isil/DE-7',
'href' => 'http://www.sub.uni-goettingen.de'
},
'timestamp' => '2019-06-11T08:04:35Z',
'version' => '0.5'
};
I would like to display the availability of each item, but I'm having a hard time iterating through the arrays inside the objects. My actual code looks like:
my $availability = $data->{document}[0]->{item}[0]->{available};
foreach my $key (#{$availability}) {
if (($key->{'service'}) eq "loan") {
print $rueckgabe = "Loan: available.\n";
} elsif (($key->{'service'}) eq "presentation") {
print $rueckgabe = "Presentation: available.\n";
} elsif (($key->{'service'}) eq "interloan") {
print $rueckgabe = "ILL: available.\n";
}
}
My expected result would be:
Item 1: Loan: available.
Item 2: Loan: available.
Iterate over the items, for each item, iterate over the availabilities.
for my $i (0 .. $#{ $data->{document}[0]{item} }) {
print 'Item ', $i + 1, ': ';
for my $availability ($data->{document}[0]{item}[$i]{available}) {
for my $key (#$availability) {
print { interloan => 'ILL' }->{ $key->{service} } || ucfirst $key->{service},
": available\n";
}
}
}

how to display json data into laravel blade?

public function bar()
{
$lowm = new LaravelOWM();
$for = $lowm->getWeatherForecast('lahore');
$ff= json_decode(json_encode($for),true);
dd($for);
}
this is the output its I think multi-dimensional array and I just want to print only few things. Tell me the answer through for each loop.
array:3 [▼
"city" => array:6 [▼
"id" => 1172451
"name" => "Lahore"
"country" => "PK"
"population" => null
"lat" => 31.5196
"lon" => 74.3263
]
"sun" => array:2 [▼
"rise" => array:3 [▼
"date" => "2018-09-17 00:48:17.000000"
"timezone_type" => 3
"timezone" => "UTC"
]
"set" => array:3 [▼
"date" => "2018-09-17 13:05:08.000000"
"timezone_type" => 3
"timezone" => "UTC"
]
]
"lastUpdate" => array:3 [▼
"date" => "2018-09-17 23:00:29.303267"
"timezone_type" => 3
"timezone" => "UTC"
]
]
I just want to display city name, lat and lon.
Why not this?
public function bar() {
$lowm = new LaravelOWM();
$for = $lowm->getWeatherForecast('lahore');
dump('City: '. $for->city->name);
dump('Latitude: '. $for->city->lat);
dump('Longitude: '. $for->city->lon);
}
More Here

how to select elements in array from multiple elements in another array

I have an array A that looks like this:
A = [ { "id" => "1234", "name" => "audi", "isCool" => false },
{ "id" => "5678", "name" => "acura", "isCool" => false },
{ "id" => "9101112", "name" => "bentley", "isCool" => true },
{ "id" => "13141516", "name" => "rollsroyce", "isCool" => true },
{ "id" => "17181920", "name" => "toyota", "isCool" => true } ]
and I have an array B that looks like this:
B = ["1234", "13141516”]
I am trying to select only elements from array A that match array A's ids with Array Bs elements.
So the returned results I would like is:
C = [ { "id" => "1234", "name" => "audi", "isCool" => false },
{ "id" => "13141516", "name" => "rollsroyce", "isCool" => true } ]
Is there an easy way to go about this?
I have currently tried this but obviously not a good idea:
a.select {|x| x['id'] == B.first || B.last}
But obviously this is not dynamic, because what if I had 3 or 4 elements in array B.
A.select { |x| B.include?(x['id']) }

Resources