array_slice для ассоциативного массива

#php #arrays #slice #associative-array

#php #массивы #фрагмент #ассоциативный массив

Вопрос:

У меня есть массив с индексами в виде временных меток. Я пытался array_slice получить все значения между временным диапазоном, но, похоже, это не работает.

 $data = array_slice(["1549440811" => 1, "1549448226" => 2, "1551108588" => 3 ], 0, 1549460338);
  

Я должен получить $data as ["1549440811" => 1, "1549448226" => 2] , но это так не работает.

Чтобы получить правильные данные, я должен использовать

 $data = array_slice(["1549440811" => 1, "1549448226" => 2, "1551108588" => 3 ], 0, 2);
  

Но проблема в том, что записи могут иметь случайные временные метки и количество записей. Итак, я не могу определить смещение, которое в данном случае равно 2.

Я знаю, что приведенный ниже код с несколькими изменениями может работать для небольшого диапазона, но не для моих временных меток, поскольку $myrange в нем было бы много данных.

 $myrange = range(0,1549460338);
$output = array_intersect(["1549440811" => 1, "1549448226" => 2, "1551108588" => 3 ] , $myrange );
  

Я избегаю перебора массива, поскольку в массиве много данных. Также мне нужно проверить много временных меток. Этот код представляет собой упрощенную логику более крупного кода с записями из базы данных, проиндексированными с помощью временных меток.

Есть ли какой-либо другой способ, которым я мог бы получить нужные данные?

Комментарии:

1. почему вы фильтруете массив, почему бы не фильтровать в запросе mysql или в любой другой используемой вами базе данных??

2. @nageennayak у меня есть цикл обработки данных, которые я получаю из базы данных, и временная метка 1549460338 относится к записи в цикле, я избегал запрашивать базу данных в цикле для извлечения других данных. Вместо этого я получил другие данные в одном запросе, проиндексированном по временной метке

3. @nageennayak другие данные, которые я извлекаю, также повторно используются другими записями в цикле

4. массив уже отсортирован по временной метке?

5. @acd да, отсортировано

Ответ №1:

Простой цикл for должен выполнять:

 $arr = ["1549440811" => 1, "1549448226" => 2, "1551108588" => 3 ];
$range = "1549460338";
foreach($arr as $k => $v) {
    if ($range > $k)
        break;
    $newArr[$k] = $v;
}
  

Вы также можете использовать array_filter (doc):

 $filtered = array_filter( $arr,
    function ($key) use ($range) {return $range > $key;},
    ARRAY_FILTER_USE_KEY
);
  

Пример: 3v4l

Редактировать:

Самый быстрый способ (считайте, что ваш массив отсортирован) — извлечь ключи с помощью $keys = array_keys($arr); , а затем выполнить поиск $range с помощью двоичного поиска ( O(log(n)) ) -> затем использовать array_slice с этим индексом.

Комментарии:

1. Я предпочитаю не выполнять цикл, поскольку данных слишком много.

2. @MehravishTemkar обновите сообщение, используя array_filter — это лучше?

3. Спасибо. позвольте мне реализовать это в моем коде и вернуться к вам

4. @MehravishTemkar на серверной части это был бы цикл

5. Спасибо. тысячи записей в массиве, а также для временных меток, избегая вещей, которые могли бы замедлить его работу. @DanyalSandeelo