get object key ending in highest number but not numerical - php

I have an stdclass object like this:
{
"type": "photo",
"photo": {
"id": id,
"album_id": album_id,
"owner_id": owner_id,
"photo_75": "https://example.com/random_unique_string/random_unique_name.jpg",
"photo_130": "https://example.com/random_unique_string/random_unique_name.jpg",
"photo_604": "https://example.com/random_unique_string/random_unique_name.jpg",
"photo_807": "https://example.com/random_unique_string/random_unique_name.jpg",
"photo_1280": "https://example.com/random_unique_string/random_unique_name.jpg",
"photo_2560": "https://example.com/random_unique_string/random_unique_name.jpg",
"width": 2560,
"height": 1440,
"text": "",
"date": 1517775329,
"access_key": "key"
}
The more complete look is on this pic:
I have my code structure like this:
foreach ( $response->posts as $key => $element ) {
if ( isset ($element->attachments) ) {
foreach ( $element->attachments as $key_att => $attachment ) {
if ( $attachment->type == 'photo' ) {
//get the value of the photo with the maximum resolution
}
}
}
}
How do I get only the value of photo_2560 in this case, pointing it to the photo_ ending with the maximum numeric value? max only works with completely numeric keys... Perhaps would need a regex, but I'm weak at that. Thanks for the help.
P. S. I asked about an array and not an object initially, so the answers given are valid, I made a mistake myself. The initial name of the question was get array key ending in highest number but not numerical. I then edited it to reflect my specific issue. Sorry about the confusion.

Here is what I would do using the little known preg_grep function:
$array = [
"photo_75"=> "https=>//example.com/random_unique_string/random_unique_name.jpg",
"photo_130"=> "https=>//example.com/random_unique_string/random_unique_name.jpg",
"photo_604"=> "https=>//example.com/random_unique_string/random_unique_name.jpg",
"photo_807"=> "https=>//example.com/random_unique_string/random_unique_name.jpg",
"photo_1280"=> "https=>//example.com/random_unique_string/random_unique_name.jpg",
"photo_2560"=> "https=>//example.com/random_unique_string/random_unique_name.jpg",
"width"=> 2560,
"height"=> 1440,
"text"=> "",
"date"=> 1517775329,
"access_key"=> "key"
];
$array = preg_grep('/^photo_\d+$/', array_keys($array));
sort($array, SORT_NATURAL);
print_r(end($array));
Output
photo_2560
Sandbox
Preg Grep lets you search an array using a regular expression, It's sort of like using array filter and preg_match
$array = array_filter($array, function($item){
return preg_match('/^photo_\d+$/', $item);
});
But obviously much shorter. Like array filter it's mostly for use against the values and not the keys, but we can use array_keys to get around this. Array Keys returns an array of the keys as the new arrays value array(0=>'key', ..) which is exactly what we want.
UPDATE
Based on this comment:
Is there an alternative of array_keys for an object? Because I confused it with an array, unfortunately.
No but you can cast it (array)$obj to an array if the properties are public. We can demonstrate this easily:
class foo{
public $bar = 'hello';
}
print_r(array_keys((array)(new foo)));
Output
array(
0 => 'bar' //which is the key 'bar' or the property named $bar
)
Sandbox
While it's not "ideal" it will work.
UPDATE1
I made edits to my question, please take a look. I don't understand how to apply your example in this case :(
I think it's $attachment->photo in your code, it's really hard to tell in the image. It's whereever the 'stuff' at the very top of you question came from, your example data.
In anycase with your code you would do something like this:
foreach ( $response->posts as $key => $element ) {
if ( isset ($element->attachments) ) {
foreach ( $element->attachments as $key_att => $attachment ) {
if ( $attachment->type == 'photo' ) {
//new code
$array = preg_grep('/^photo_\d+$/', array_keys((array)$attachment->photo));
sort($array, SORT_NATURAL);
$result = end($array);
print_r($result);
}
} //end foreach
}
}//end foreach
By the way the Regex I am using ^photo_\d+$ is basically this
^ match the start of the string
photo_ match "photo_" litterally
\d+ match one or more digits
$ match the end of the string.
Note the ^ can have different meaning depending where it is, for example if its in a character class [0-9] (A range of characters 0 to 9 same as \d) like this [^0-9] it means NOT so it makes the character class match everything but what is in it. Or "negation". Which is a bit confusing, but that is how it works. In this case it would be anything NOT a digit.
By using the ^ and $ we are saying that our Regex must match the whole string. So we can avoid things like somephoto_79890_aab which if we didn't have the start and end markers our Regex photo_\d+ would match this part some[photo_79890]_aab.
Cheers.

Regex won't tell you what the highest number is. But, these "photo_N" keys can be sorted using natural order.
You didn't mention the name of your variable, so I'll just assume $array here for the sake of convenience.
Let's first get only the "photo_N" elements from the array:
$photos = array_filter(
$array['photo'],
function($key) {
return substr($key, 0, 6) === "photo_";
},
ARRAY_FILTER_USE_KEY
);
We can now sort the result of that by key, using natural order:
ksort($photos, SORT_NATURAL);
This should have put the photo with the highest numerical key at the end, so you can get its value using:
$photo = end($photos);

Related

Regular expression to get the value from array

I need to get the value for a certain key, they key is not the same all the time.
initial part remains same but every time I get new id added in the end.
My array is like this:
senario 1:
Array
(
[custom_194_1] => 123
[_f_upload] => Save
)
senario 2:
Array
(
[custom_194_2] => 456
[_f_upload] => Save
)
I need to get the value 123 in senario 1, 456 in senario 2.
Can anyone please help me on how to get the value from this array key.
If your key is always the first element, and the array is $array the fastest way is:
$result = reset($array);
Or if you don't want to mess with the array's internal pointer:
$result = array_values($array)[0];
If you want the value of the key:
$key = array_keys($array)[0];
Thanks for your time guys. I'm using foreach to loop through and then checking with every key with substring. Hope it helps someone in future, not the very best solution though.
foreach($fields as $key => $val)
{
if(substr($key,0,10)=='custom_194'){
$realValue = $val;
echo "<br>value i'm looking for:";print_r($val);
}
}
Because you stated that you want the number at the end of the key and because you appear to want to learn more about regular expressions... This is not a hard task to do with preg_match.
Assume $array is the array that you begin with that has all the key=>val values.
foreach($fields as $key=>$val)
{
if(preg_match('/^custom_194_([0-9]+)$/', $key, $matches))
{
$num = $matches[1];
print "Key number $num has value $val\n";
}
}
The regular expression is ^custom_194_([0-9]+)$. The ^ means "beginning of the string." The $ means "end of the string." You can see that we explicitly spell out custom_194_. Then, we use ( and ) to identify a substring that we want to keep in the matches array. Inside ( and ), we look for the characters 0 through 9 using [0-9]. The + means "1 or more characters." So, we want 1 or more 0 through 9 characters.
The match array contains the entire string matched in the first index and then each sub-match in the remaining indexes. We only have one sub-match, which will be in index 1. So, $num is in $matches[1].

PHP: How to extract this string

Suppose I've got the following string:
) [6] => Array ( [2014-05-05 00:0] => My actual content
If I want to only be left with My actual content at the end, what is the best way to split the entire string?
Note: the words My actual content are and can change. I'm hoping to cut the string based on the second => string as this will be present at all times.
It seems you're just looking to find the first value of an array with keys you do not know. This is super simple:
Consider the following array:
$array = array(
'2014-05-22 13:36:00' => 'foo',
'raboof' => 'eh',
'qwerty' => 'value',
'8838277277272' => 'test'
);
Method #1:
Will reset the array pointer to the first element and return it.
Using reset:
var_dump( reset($array) ); //string(3) "foo"
DEMO
Method #2:
Will reset the entire array to use keys of 0, 1, 2, 3...etc. Useful if you need to get more than one value.
Using array_values:
$array = array_values($array);
var_dump( $array[0] ); //string(3) "foo"
DEMO
Method #2.5:
Will reset the entire array to use keys of 0, 1, 2, 3...etc and select the first one into the $content variable. Useful if you need to get more than one value into variables straight away.
Using list and array_values:
list( $content ) = array_values($array);
var_dump( $content ); //string(3) "foo"
DEMO
Method #3:
Arrays are iteratable, so you could iterate through it but break out immediately after the first value.
Using a foreach loop but break immediatly:
foreach ($array as $value) {
$content = $value;
break;
}
var_dump($content); //string(3) "foo"
DEMO
To Answer your question, on extracting from a string based on last 'needle'...
Okay, this is quite an arbitrary question, since it seems like you're showing us the results from a print_r(), and you could reference the array key to get the result.
However, you mentioned "... at the end", so I'm assuming My actual content is actually right at the end of your "String".
In which case there's a very simple solution. You could use: strrchr from the PHP manual - http://www.php.net/manual/en/function.strrchr.php.
So you're looking at this: strrchr($string, '=>');
Hope this answers your question. Advise otherwise if not please.
you have to use foreach loop in a foreach to get the multi dimentional array values.
foreach($value as $key){
foreach($key as $val){
echo $val;
}
}

regex to parse a string with known string seprarators

I'm trying to split a concatenated string of key1value1key2value2
The problem is I can't know in which order they are
$k = preg_split("/(name|age|sex)/", "nameJohnage27sexM");
var_dump($k);
$k = preg_split("/(sex|name|age)/", "age27sexM");
var_dump($k);
So I can't know if the age or name will be 1st or 2nd index of $k, don't even know also if "name" key is in the string, there can be a limited set of key
How to do?
edit: solved like this, tx mario
for ($i=1, $n=count($k)-1; $i<$n; $i+=2) {
$s[$k[$i]] = $k[$i+1];
}
var_dump($s);
This somewhat clumsy pattern will return a key-value list:
/(?:(name|age|sex)(.+?(?=(?:name|age|sex|\z))))/g
Thus preg_match using the above on "nameJohnage27sexM" should return the array
["name", "John", "age", "27", "sex", "MAN"]
This makes it possible to create the array ["name" => "John", ...] by iterating over the elements above.

How To Create A New Array Of First Names From Array Of First And Last Names?

Hey all. I need to create an array of first names from another array of first and last names. So basically the original array with first and last names looks like this:
Original Array
array("John Doe", "Jane Doe", "John Darling", "Jane Darling");
And the array I need to create from that would be:
New Array
array("John", "Jane", "John", "Jane");
So I guess for each value I would need to remove whatever comes after the space. If someone can point me in the correct direction to use regular expressions or some array function that would be great.
Cheers!
Update:
Thank you all for your answers.
You can create a callback function that strips the last names, and map it to the array, like so (I use a different approach rather than explode(), both are equally valid methods):
function strip_last_name($name) {
if (($pos = strpos($name, ' ')) !== false) {
// If there is at least one space present, assume 'first<space>last'
return substr($name, 0, $pos);
} else {
// Otherwise assume first name only
return $name;
}
}
$first_names = array_map('strip_last_name', $full_names);
This preserves the array keys and the order of elements.
this should do the trick, and if it shouldn't I'm really sorry but haven't slept this night :P, but you'll get the idea ;)
<?php
$secondarray=array();
foreach($firstarray as $fullname){
$s=explode(' ',$fullname);
$secondarray[]=$s[0];
}
?>
$array1 = array("John Doe", "Jane Doe", "John Darling", "Jane Darling");
$array2 = array();
foreach ($array1 as $name) {
$firstname = explode(' ',$name);
$array2[] = $firstname[0];
}
The explode function splits a string by a delimiter, for example explode('b','aaaaabccccc') returns array('aaaaa','ccccc'). The above code uses this, with a foreach loop, to split each full name into an array containing the first and last name, and then add the first name to an array like the first one.

How do I move an array element with a known key to the end of an array in PHP?

Having a brain freeze over a fairly trivial problem. If I start with an array like this:
$my_array = array(
'monkey' => array(...),
'giraffe' => array(...),
'lion' => array(...)
);
...and new elements might get added with different keys but always an array value. Now I can be sure the first element is always going to have the key 'monkey' but I can't be sure of any of the other keys.
When I've finished filling the array I want to move the known element 'monkey' to the end of the array without disturbing the order of the other elements. What is the most efficient way to do this?
Every way I can think of seems a bit clunky and I feel like I'm missing something obvious.
The only way I can think to do this is to remove it then add it:
$v = $my_array['monkey'];
unset($my_array['monkey']);
$my_array['monkey'] = $v;
array_shift is probably less efficient than unsetting the index, but it works:
$my_array = array('monkey' => 1, 'giraffe' => 2, 'lion' => 3);
$my_array['monkey'] = array_shift($my_array);
print_r($my_array);
Another alternative is with a callback and uksort:
uksort($my_array, create_function('$x,$y','return ($y === "monkey") ? -1 : 1;'));
You will want to use a proper lambda if you are using PHP5.3+ or just define the function as a global function regularly.
I really like #Gordon's answer for its elegance as a one liner, but it only works if the targeted key exists in the first element of the array. Here's another one-liner that will work for a key in any position:
$arr = ['monkey' => 1, 'giraffe' => 2, 'lion' => 3];
$arr += array_splice($arr, array_search('giraffe', array_keys($arr)), 1);
Demo
Beware, this fails with numeric keys because of the way that the array union operator (+=) works with numeric keys (Demo).
Also, this snippet assumes that the targeted key is guaranteed to exist in the array. If the targeted key does not exist, then the result will incorrectly move the first element to the end because array_search() will return false which will be coalesced to 0 by array_splice() (Demo).
You can implement some basic calculus and get a universal function for moving array element from one position to the other.
For PHP it looks like this:
function magicFunction ($targetArray, $indexFrom, $indexTo) {
$targetElement = $targetArray[$indexFrom];
$magicIncrement = ($indexTo - $indexFrom) / abs ($indexTo - $indexFrom);
for ($Element = $indexFrom; $Element != $indexTo; $Element += $magicIncrement){
$targetArray[$Element] = $targetArray[$Element + $magicIncrement];
}
$targetArray[$indexTo] = $targetElement;
}
Check out "moving array elements" at "gloommatter" for detailed explanation.
http://www.gloommatter.com/DDesign/programming/moving-any-array-elements-universal-function.html

Categories