Примечание. Ответ @Matthews правильный, но если вы находитесь в другом потоке, и вы вызываете вызов волейбола, когда у вас нет интернета, ваш обратный вызов будет вызываться в основном потоке, но поток, на котором вы находитесь, будет заблокирован FOREVER. (Поэтому, если этот поток является IntentService, вы никогда не сможете отправить ему другое сообщение, и ваша служба будет в основном мертвой).
Используйте версию get()
с таймаутом future.get(30, TimeUnit.SECONDS)
и поймать ошибку, чтобы выйти из вашего потока.
Чтобы ответить на ответ @Mathews:
try {
return future.get(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// exception handling
} catch (ExecutionException e) {
// exception handling
} catch (TimeoutException e) {
// exception handling
}
Ниже я завернул его в метод & amp; используйте другой запрос:
/**
* Runs a blocking Volley request
*
* @param method get/put/post etc
* @param url endpoint
* @param errorListener handles errors
* @return the input stream result or exception: NOTE returns null once the onErrorResponse listener has been called
*/
public InputStream runInputStreamRequest(int method, String url, Response.ErrorListener errorListener) {
RequestFuture<InputStream> future = RequestFuture.newFuture();
InputStreamRequest request = new InputStreamRequest(method, url, future, errorListener);
getQueue().add(request);
try {
return future.get(REQUEST_TIMEOUT, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Log.e("Retrieve cards api call interrupted.", e);
errorListener.onErrorResponse(new VolleyError(e));
} catch (ExecutionException e) {
Log.e("Retrieve cards api call failed.", e);
errorListener.onErrorResponse(new VolleyError(e));
} catch (TimeoutException e) {
Log.e("Retrieve cards api call timed out.", e);
errorListener.onErrorResponse(new VolleyError(e));
}
return null;
}
Это не сохраняет первоначальный порядок ввода, но потому что данные проиндексированы, поэтому я предполагаю, что это не имеет значения.
Имея всего 3 вызова в одной строке, вы назначаете временные ассоциативные ключи сзади вперед, чтобы исключить последние дубликаты (поскольку php не разрешает дублирование ключей), а затем при желании удаляете временные ключи с помощью array_values()
. Нет повторных вызовов функций. Нет массивов поиска.
Код: ( Демонстрация )
$array = [
['id_card' => 11883834, 'type' => 1, 'registed' => 1547610891],
['id_card' => 20311077, 'type' => 1, 'registed' => 1547610891],
['id_card' => 16187903, 'type' => 3, 'registed' => 1547610891],
['id_card' => 16354099, 'type' => 1, 'registed' => 1547610891],
['id_card' => 21133393, 'type' => 4, 'registed' => 1547610891],
['id_card' => 15452852, 'type' => 2, 'registed' => 1547610891],
['id_card' => 19775869, 'type' => 2, 'registed' => 1547610891],
['id_card' => 20311077, 'type' => 1, 'registed' => 1547610891],
['id_card' => 21133393, 'type' => 4, 'registed' => 1547610891],
['id_card' => 11883834, 'type' => 1, 'registed' => 1547610891]
];
var_export(array_values(array_column(array_reverse($array), null, 'id_card')));
Если вы передумаете желать сохранить первое вхождение, вы можете удалить array_reverse()
. Если клавиши первого уровня не имеют значения на выходе, вы можете удалить array_values()
. Эти изменения позволили бы решить проблему как вызов одной функции.
p.s. "REGIST эр ред"
Таким образом, проблема заключается в том, что решения array_unique
ожидают, что все значение будет эквивалентным - они не просто сравниваются на основе вашего поля идентификатора.
Вместо этого вы, вероятно, захотите пройтись по массиву и отследить, какие идентификаторы вы видели, и взять только те элементы, для которых вы раньше не видели идентификатор.
function filter_duplicate_id_cards($data) {
$seen = array(); // To keep track of the IDs we've seen
$filtered = array(); // Will hold the result
foreach($data as $item) {
if(array_key_exists($item['id_card'], $seen)) {
// We already encountered this id card before.
continue;
}
// Never-before seen id card, append it to the result and set the key in $seen
$filtered[] = $item;
$seen[$item['id_card']] = TRUE;
}
return $filtered;
}
Обратите внимание, что здесь используется форма карты массива PHP, а не просто добавление видимых идентификаторов в форму списка и использование чего-то вроде in_array
для проверки, видели ли мы ключ. Это важно с точки зрения производительности, особенно если мы собираемся работать с большими наборами данных - in_array
- это O (n) с количеством элементов в массиве, тогда как array_key_exists
- это O (1).
Более общая версия этой функции будет выглядеть следующим образом:
function filter_duplicate_field($data, $field) {
$seen = array(); // To keep track of the keys we've seen
$filtered = array(); // Will hold the result
foreach($data as $item) {
if(array_key_exists($item[$field], $seen)) {
// We already encountered this key before.
continue;
}
// Never-before seen key, append it to the result and set the key in $seen
$filtered[] = $item;
$seen[$item[$field]] = TRUE;
}
return $filtered;
}
Вы можете затем назвать ее как $result = filter_duplicate_field($data, 'id_card');
.