получить ключ объекта, заканчивающийся наибольшим числом, но не числовым - PullRequest
0 голосов
/ 04 марта 2019

У меня есть объект stdclass, подобный этому:

  {
    "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"
    }

Более полный вид на этой картинке: enter image description here

У меня есть такая структура кода, как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
            }
       }
    }
}

Как получить в этом случае только значение photo_2560, указывая его на photo_, заканчивающееся максимальным числовым значением?max работает только с полностью числовыми клавишами ... Возможно, потребуется регулярное выражение, но я слаб в этом.Спасибо за помощь.

PS Сначала я спросил о массиве, а не об объекте, поэтому приведенные ответы верны, я сам допустил ошибку.Первоначальное название вопроса было get array key ending in highest number but not numerical.Затем я отредактировал его, чтобы отразить мою конкретную проблему.Извините за путаницу.

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Вот что я бы сделал, используя малоизвестную функцию preg_grep:

$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));

Вывод

 photo_2560

Песочница

Preg Grep позволяет искать в массиве с помощью регулярного выражения. Это похоже на использование фильтра массива и preg_match

   $array = array_filter($array, function($item){
        return preg_match('/^photo_\d+$/', $item);
   });

Но, очевидно, намного короче.Как и фильтр массива, он в основном используется для значений, а не для ключей, но мы можем использовать array_keys, чтобы обойти это.Array Keys возвращает массив ключей в виде нового значения массива array(0=>'key', ..), которое именно то, что мы хотим.

ОБНОВЛЕНИЕ

На основании этого комментария:

Есть ли альтернатива array_keys для объекта?К сожалению, я перепутал его с массивом.

Нет, но вы можете преобразовать его (array)$obj в массив, если свойства общедоступны.Мы можем легко это продемонстрировать:

class foo{

    public $bar = 'hello';
}

print_r(array_keys((array)(new foo)));

Вывод

 array(
      0 => 'bar' //which is the key 'bar' or the property named $bar
 )

Песочница

Хотя это не "идеально", оно будет работать.

ОБНОВЛЕНИЕ1

Я внес изменения в свой вопрос, пожалуйста, посмотрите.Я не понимаю, как применить ваш пример в этом случае: (

Я думаю, что это $attachment->photo в вашем коде, это действительно трудно сказать на изображении.самый верхний из ваших вопросов пришел, ваш пример данных.

В любом случае с вашим кодом вы бы сделали что-то вроде этого:

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

Кстати, Regex, который я использую ^photo_\d+$ в основном это

  • ^ соответствует началу строки
  • photo_ соответствует буквенно "photo_"
  • \d+ соответствует одной или нескольким цифрам
  • $ соответствует концу строки.

Обратите внимание, что ^ может иметь различное значение в зависимости от его местоположения, например, если оно находится в классе символов [0-9](Диапазон символов от 0 до 9 такой же, как \d), например [^0-9], это означает НЕ , поэтому класс символов соответствует всему, кроме того, что в нем. Или «отрицание»Это немного сбивает с толку, но так оно и работает. В этом случае это будет что-то, а НЕ цифра.

Используя ^ и $, мы говорим, что наше регулярное выражение должно соответствовать всей строке.Таким образом, мы можем избежать таких вещей, как somephoto_79890_aab, которые, если бы у не было маркеров начала и конца, наше регулярное выражение photo_\d+ соответствовало бы этой части some[photo_79890]_aab.

Приветствия.*

0 голосов
/ 04 марта 2019

Regex не скажет вам, какое наибольшее число.Но эти ключи «photo_N» можно отсортировать в естественном порядке.

Вы не упомянули имя своей переменной, поэтому для удобства я просто приму здесь $array.

Давайте сначала получим только элементы "photo_N" из массива:

$photos = array_filter(
    $array['photo'],
    function($key) {
        return substr($key, 0, 6) === "photo_";
    },
    ARRAY_FILTER_USE_KEY
);

Теперь мы можем отсортировать результат по ключу, используя естественный порядок:

ksort($photos, SORT_NATURAL);

Это должно было поставить фото с наибольшим цифровым ключом в конце, чтобы вы могли получить его значение, используя:

$photo = end($photos);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...