Quickest way to check an array of classed for an item? - php

I have a class with values:
Array
(
[0] => stdClass Object
(
[id] => 1
[val] => one
)
[1] => stdClass Object
(
[id] => 2
[val] => two
)
[2] => stdClass Object
(
[id] => 3
[val] => three
)
)
What is the quickest way to search this array to see if there is an item with id = 2? I know this will work:
$hasTwo = false;
foreach ($arrayItems as $arrayItem) {
if ($arrayItem->id == 2) {
$hasTwo = true;
break;
}
}
if ($hasTwo) {
// do what I wanted to do...
}
Is there no easier way that requires less code that can do the same?

Perhaps
$hasTwo = array_filter(
$arrayItems,
function($value) {
return $value->id == 2;
}
);
but you'll need to test which is the faster, and the answer is probably your original code

Related

select array value of an object in php

I'm just a beginner and would like to select a value of an array inside an object. I'm quite lost and don't know how to do.
ie : how to get de value of "thailande" inside this object ?
Forminator_Form_Entry_Model Object
(
[entry_id] => 42
[entry_type] => custom-forms
[form_id] => 24342
[is_spam] => 0
[date_created_sql] => 2020-07-02 11:42:21
[date_created] => 2 Juil 2020
[time_created] => 2 Juil 2020 # 11:42
[meta_data] => Array
(
[select-1] => Array
(
[id] => 87
[value] => thailande
)
[radio-1] => Array
(
[id] => 88
[value] => 1
)
[number-1] => Array
(
[id] => 89
[value] => 10
)
[_forminator_user_ip] => Array
(
[id] => 90
[value] => 84.101.156.169
)
)
[table_name:protected] => politis_5_frmt_form_entry
[table_meta_name:protected] => politis_5_frmt_form_entry_meta
)
thx a lot for your help.
It's fairly straightforward - you just go down the hierarchy one step at a time referencing the index you need.
So, assuming $obj in this example is an instance of Forminator_Form_Entry_Model then you would write
$obj->meta_data["select-1"]["value"]
which will point to the data you're looking for.
N.B. The ->index syntax is used to get properties of an object. the ["index"] syntax is used to get properties of an array.
You can try Callback Functions
function array_search_id($val_for_search, $array_data, $search_in_path='root') {
if(is_array($array_data) && count($array_data) > 0) { // if value has child
foreach($array_data as $key => $value) {
$paths_list = $search_in_path;
// Adding current key to search path
array_push($paths_list, $key);
if(is_array($value) && count($value) > 0) { // if value has child
$res = array_search_id($val_for_search, $value, $paths_list);//callback function
if ($res != null)
return $res;
}
else if($value == $val_for_search){
//if you wants path + result
return end($paths_list);
/*
//if you wants path
return join(" --> ", $paths_list);
*/
} //if value find in array return val
}
}
return null;
}
array_search_id('thailande', $your_array);

PHP: Update objects array values with another unsorted objects array

I have two objects arrays.
First array $x:
[0] => stdClass Object
(
[id] => 54
[value] => test54
[something] => testtest54
)
[1] => stdClass Object
(
[id] => 21
[value] => test21
[something] => testtest21
)
...
Second array $y:
[0] => stdClass Object
(
[id] => 21
[value] => test21_new_value
)
[1] => stdClass Object
(
[id] => 54
[value] => test54_new_value
)
...
I want to update my first array $x importing value of the second array's ($y) field which has the same id, I want to have :
[0] => stdClass Object
(
[id] => 54
[value] => test54_new_value
[something] => testtest54
)
[1] => stdClass Object
(
[id] => 21
[value] => test21_new_value
[something] => testtest21
)
...
I can do something like this :
foreach($x as $k => $v) {
foreach($y as $k2 => $v2) {
if ($v->id === $v2->id) $x[$k]->value = $v2->value;
}
}
But I don't like this, because I have to walk on array $y for each $x (if I have 100 items in $x and 100 items in $y, it loops 100*100 times). I think there is a more efficient, elegant or optimized way to do this, but I don't know how to do that (I did not found a precise response to this specific problem, so I ask here).
Sure. Usually you'd use an associative array for this (with the key being the unique ID), as this would mean (100 + 100) iterations instead of (100 * 100):
<?php
$assocX = array();
foreach ($x as $v) {
$assocX[$v->id] = $v;
}
foreach ($y as $v) {
$v->something = $assocX[$v->id]->something;
}
?>
If you can't be sure that the value exists in $x you can also check for this ("no value" would be translated to NULL):
<?php
$assocX = array();
foreach ($x as $v) {
$assocX[$v->id] = $v;
}
foreach ($y as $v) {
$v->something = (isset($assocX[$v->id]) ? $assocX[$v->id]->something : null);
}
?>

Getting all values from a specific array within a multidimentional array

I've been searching around quite a bit for an answer for this, but I'm afraid that I've been unable to figure out a solution to this problem. I've created a multidimensional array which includes zip code information. However, I've been unable to pull the values out of it in the way that I need to. Here's an example of the print_r():
Array (
[0] => Array (
[0] => 59101
[1] => 0.0 )
[1] => Array (
[0] => 59102
[1] => 5.0 )
[2] => Array (
[0] => 59105
[1] => 6.8 )
[3] => Array (
[0] => 59106
[1] => 9.2 )
[4] => Array (
[0] => 59037
[1] => 12.7 )
[5] => Array (
[0] => 59044
[1] => 13.9 )
[6] => Array (
[0] => 59002
[1] => 16.6 )
[7] => Array (
[0] => 59079
[1] => 19.3 )
)
I need to look through the array for a specific zip code, and then get distance (the second value in each array) associated with that zip code. I'd considered restructuring the array, but I'm unsure of how to accomplish it. Here's my current code:
EDIT## sorry, I may not have been clear. The below code is what I'm using to build the array, not to extract information from the array. I have not idea how to get the information out of the array.
$rArray = array();
foreach ($points as $point){
$zips = $point->Postcode;
$dists = number_format($point->D,1);
array_push($rArray,array($zips,$dists));
}
Any thoughts on the best way to accomplish this? Thanks!
This?
EDIT: After your question update.
function getDistanceByZip($zip) {
$array = //your array here;
foreach($array as $value) {
if($zip == $value[0]) {
return $value[1];
}
}
return false;
}
Maybe this?
foreach ($points as $point){
if ($point->Postcode === $codeIamLookingFor) {
echo "Distance: " . number_format($point->D, 1);
}
}
function arrayseek($array, $zip){
foreach($array as $k => $v){
if($v[0] == $zip){
return $v[1];
}
}
return false;
}

PHP prevent foreach loop from overwriting object

This is the fourth time I've tried writing this question, so please bear with me.
I have a PHP object that comes from a DB Query which pulls back the following data:
[1] => stdClass Object
(
[eventId] => 11
[eventName] => Second Event
[...]
[eventChildren] => Array
(
[0] => stdClass Object
(
[childId] => 8
[childName] => Jane Doe
[...]
[gifts] => Array
(
[0] => stdClass Object
(
[giftId] => 73
[giftName] => My two front teeth
[childId] => 8
[userId] => 1
[eventId] => 11
)
[1] => stdClass Object
(
[giftId] => 74
[giftName] => Wasps
[childId] => 8
[userId] => 1
[eventId] => 11
)
)
)
)
)
)
I'm then running a massive series of foreach loops in order to compare the userId from the gifts array against the userId stored in the session cookie.
From these loops I'm creating an array of children and gifts that the user has selected.
The problem is this overwrites my main object rather than creating a new one.
The Loops:
$user = $this->session->userdata('user');
$tempEvents = $events;
$userSelection = array();
$flag = FALSE;
foreach ( $tempEvents as $i => $event )
{
if ( $i == 0 )
{
foreach ( $event->eventChildren as $child )
{
$userGift = array();
foreach ( $child->gifts as $gift )
{
if ( $gift->userId == $user['userId'] )
{
array_push($userGift, $gift);
$flag = TRUE;
}
}
$tempChild = $child;
$tempChild->gifts = $userGift;
if ( $flag )
{
array_push($userSelection, $tempChild);
$flag = FALSE;
}
}
}
}
If I print_r($events); it displays the edited list rather than it's full list of events. Is there a way to create a duplicate object and edit that rather than editing the original object?
The reason for the "overwriting" is $tempChild = $child;.
That will not deep copy the contents of $child but make both $tempChild and $child point towards the same data structure, which obviously isn't desirable in this case.
You should use clone as in the below example.
$tempChild = clone $child;
PHP: Object Cloning - Manual
Try
$tempEvents = clone $events;

How can I create multidimensional arrays from a string in PHP?

So My problem is:
I want to create nested array from string as reference.
My String is "res[0]['links'][0]"
So I want to create array $res['0']['links']['0']
I tried:
$result = "res[0]['links'][0]";
$$result = array("id"=>'1',"class"=>'3');
$result = "res[0]['links'][1]";
$$result = array("id"=>'3',"class"=>'9');
when print_r($res)
I see:
<b>Notice</b>: Undefined variable: res in <b>/home/fanbase/domains/fanbase.sportbase.pl/public_html/index.php</b> on line <b>45</b>
I need to see:
Array
(
[0] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 1
[class] => 3
)
)
)
[1] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 3
[class] => 9
)
)
)
)
Thanks for any help.
So you have a description of an array structure, and something to fill it with. That's doable with something like:
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
// unoptimized, always uses strings
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
array_create( $res, "[0]['links'][0]", array("id"=>'1',"class"=>'3') );
array_create( $res, "[0]['links'][1]", array("id"=>'3',"class"=>'9') );
Note how the array name itself is not part of the structure descriptor. But you could theoretically keep it. Instead call the array_create() function with a $tmp variable, and afterwards extract() it to achieve the desired effect:
array_create($tmp, "res[0][links][0]", array(1,2,3,4,5));
extract($tmp);
Another lazy solution would be to use str_parse after a loop combining the array description with the data array as URL-encoded string.
I have a very stupid way for this, you can try this :-)
Suppose your string is "res[0]['links'][0]" first append $ in this and then put in eval command and it will really rock you. Follow the following example
$tmp = '$'.'res[0]['links'][0]'.'= array()';
eval($tmp);
Now you can use your array $res
100% work around and :-)
`
$res = array();
$res[0]['links'][0] = array("id"=>'1',"class"=>'3');
$res[0]['links'][0] = array("id"=>'3',"class"=>'9');
print_r($res);
but read the comments first and learn about arrays first.
In addition to mario's answer, I used another function from php.net comments, together, to make input array (output from jquery form serializeArray) like this:
[2] => Array
(
[name] => apple[color]
[value] => red
)
[3] => Array
(
[name] => appleSeeds[27][genome]
[value] => 201
)
[4] => Array
(
[name] => appleSeeds[27][age]
[value] => 2 weeks
)
[5] => Array
(
[name] => apple[age]
[value] => 3 weeks
)
[6] => Array
(
[name] => appleSeeds[29][genome]
[value] => 103
)
[7] => Array
(
[name] => appleSeeds[29][age]
[value] => 2.2 weeks
)
into
Array
(
[apple] => Array
(
[color] => red
[age] => 3 weeks
)
[appleSeeds] => Array
(
[27] => Array
(
[genome] => 201
[age] => 2 weeks
)
[29] => Array
(
[genome] => 103
[age] => 2.2 weeks
)
)
)
This allowed to maintain numeric keys, without incremental appending of array_merge. So, I used sequence like this:
function MergeArrays($Arr1, $Arr2) {
foreach($Arr2 as $key => $Value) {
if(array_key_exists($key, $Arr1) && is_array($Value)) {
$Arr1[$key] = MergeArrays($Arr1[$key], $Arr2[$key]);
}
else { $Arr1[$key] = $Value; }
}
return $Arr1;
}
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
$input = $_POST['formData'];
$result = array();
foreach ($input as $k => $v) {
$sub = array();
array_create($sub, $v['name'], $v['value']);
$result = MergeArrays($result, $sub);
}

Categories