2010-08-17 2 views
2

Начиная с массива с значениями 10K. Я хочу случайным образом получить 1000 значений и поместить их в другой массив.Получите подмножество случайных значений из массива php

Прямо сейчас, я использую цикл for для получения значений, но я хочу выбрать 1000 значений и не зацикливать 1000 раз. Функция array_slice работает, но не дает случайных значений. Какова правильная (наиболее эффективная) функция для этой задачи.

код прямо сейчас

$seedkeys = (...array.....); 

for ($i=0; $i<1000; $i++) { 
     $random = array_rand($seedkeys); 
    $randseed[$i] = $seedkeys[$random]; 

}//for close 

Тиа

ответ

2

Ну, есть несколько альтернатив. Я не уверен, какой из них самый быстрый, поскольку вы имеете дело с массивным массивом, но вы можете попробовать их:

Вы можете использовать shuffle, который будет случайным образом определять весь массив. Это, вероятно, будет иметь лучшую производительность, так как вы потребляете значительную часть массива (10%).

shuffle($seedkeys); 
$result = array_slice($seedkeys, 0, 1000); 

Вы можете использовать array_rand (как уже было сказано) в усадьбе, задающее Том Хей. Это потребует копирования ключей, поэтому, если вы имеете дело со значительной частью исходного массива, это может быть не самым быстрым. (Обратите внимание на использование array_flip, это необходимо, чтобы разрешить использование array_intersect_key:

$keys = array_flip(array_rand($seedkeys, 1000)); 
$result = array_intersect_key($seedkeys, $keys); 

Если память плотно, лучшее решение (кроме MySQL один) будет цикл, так как он не требует массивов быть Обратите внимание, что это будет медленнее, но если массив содержит много информации, он может компенсировать медленность за счет большей эффективности памяти (поскольку он только копирует именно то, что он возвращает) ...

$result = array(); 
for ($i = 0; $i < 1000; $i++) { 
    $result[] = $seedkeys[array_rand($seedkeys)]; 
} 

Вы можете сделать это в MySQL (предполагая, что данные для массива начинаются с MySQL). Помните, что это просто, но не так эффективно (См Jan Kneschke's post) ...

SELECT * FROM `foo` ORDER BY RAND() LIMIT 1000; 
+0

Спасибо maxell, мне, возможно, придется идти по маршруту sql. Размер массива слишком велик, и он вызывает проблемы с памятью, и цикл выбирает только несколько повторяющихся ключей. – jamex

0

Вы можете использовать array_rand(), чтобы получить несколько элементов?

$random_keys = array_rand($seedkeys, 1000); 
shuffle($random_keys); 

Это даст вам множество случайных ключей, поэтому, чтобы получить массив значений, что вам нужно сделать что-то вроде этого:

$result = array(); 
foreach ($random_keys as $rand_key) { 
    $result[] = $seedkeys[$rand_key]; 
} 

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

$result = array_intersect_key($seedkeys, array_flip($random_keys)); 
+0

Благодаря Тому, массиву пересекаться работает как рекламируется, но только тогда, когда у меня есть меньший массив, большие массивы возвращают напуганные повторяющиеся значения/ключи из-за проблемы с памятью (та же проблема, как мой оригинальный метод цикла). – jamex

Смежные вопросы