#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