从数组中选择 n 个随机值

发布于 2024-09-17 06:54:42 字数 176 浏览 12 评论 0原文

我有一个对象数组,我需要随机选择其中 8 个。我最初的想法是使用 array_rand(array_flip($my_array), 8) 但这不起作用,因为对象不能充当数组的键。

我知道我可以使用 shuffle,但我担心随着数组大小的增加,性能会受到影响。这是最好的方法,还是有更有效的方法?

I have an array of objects and I need to select 8 of them at random. My initial thought was to use array_rand(array_flip($my_array), 8) but that doesn't work, because the objects can't act as keys for an array.

I know I could use shuffle, but I'm worried about performance as the array grows in size. Is that the best way, or is there a more efficient way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

审判长 2024-09-24 06:54:42
$result = array();
foreach( array_rand($my_array, 8) as $k ) {
  $result[] = $my_array[$k];
}
$result = array();
foreach( array_rand($my_array, 8) as $k ) {
  $result[] = $my_array[$k];
}
焚却相思 2024-09-24 06:54:42
$array = array();
shuffle($array); // randomize order of array items
$newArray = array_slice($array, 0, 8);

请注意,shuffle() 函数提供参数作为引用并对其进行更改。

$array = array();
shuffle($array); // randomize order of array items
$newArray = array_slice($array, 0, 8);

Notice that shuffle() function gives parameter as a reference and makes the changes on it.

对不⑦ 2024-09-24 06:54:42

您可以使用 array_rand 随机选择键,并使用 foreach 收集对象:

$objects = array();
foreach (array_rand($my_array, 8) as $key) {
    $objects[] = $my_array[$key];
}

You could use array_rand to pick the keys randomly and a foreach to gather the objects:

$objects = array();
foreach (array_rand($my_array, 8) as $key) {
    $objects[] = $my_array[$key];
}
你另情深 2024-09-24 06:54:42

我刚刚在我们的代码中发现了这一点,并希望找到一个更具可读性的解决方案:

$rand = array_intersect_key($all, array_flip(array_rand($all, $count)));

I just found this in our code and was hoping to find a more readable solution:

$rand = array_intersect_key($all, array_flip(array_rand($all, $count)));
眼眸里的那抹悲凉 2024-09-24 06:54:42

有多种方法可以完成此任务,但不同的方法会提供微妙的结果。如果值是对象或任何其他数据类型,则没有区别。我的演示将使用从 1 到 9 的数字范围。

“shuffle & slice”

  • 简洁易读,但 shuffle 不必要地对整个数组进行洗牌,尽管只需要一个子集。
  • 不是单行代码,因为 shuffle() 通过引用进行修改。
  • 结果键将被索引,值将具有随机顺序。

代码:(Demo)

shuffle($array);
var_export(array_slice($array, 0, 8));
//e.g.  [2, 8, 6, 9, 3, 5, 4, 1]

shuffle($array);
var_export(array_slice($array, -8));
//e.g.  [7, 3, 6, 8, 4, 1, 2, 5]


“array_rand (w/ count) & iterate”

  • 不太简洁,但仍然可读。
  • 可以写成一行字。
  • 结果键将被索引,值将按其在输入数组中的位置排序。

经典 foreach:(演示)

$result = [];
foreach (array_rand($array, 8) as $key) {
    $result[] = $array[$key];
}
var_export($result);
//e.g. [1, 2, 3, 4, 5, 6, 7, 8]

函数式单行:(Demo)

var_export(
    array_map(fn($k) => $array[$k], array_rand($array, 8))
);
//e.g. [1, 3, 4, 5, 6, 7, 8, 9]


"array_rand (w/ count) & Flip & intersect_key"

  • 比较简洁,可读性较差,调用 3 个迭代器,而不是前面提到的 2 个。
  • 可以写成一行字。
  • 结果键可能不会被索引,但值将按其在输入数组中的位置排序。

代码:(演示)

var_export(
    array_intersect_key($array, array_flip(array_rand($array, 8)))
);
//e.g. [1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6, 6 => 7, 7 => 8, 8 => 9]


“array_rand的循环调用”

  • 不太简洁,可读性较好,并且进行了迭代函数调用。
  • 可以写成一行代码,但是调用 range() 并不是超级优雅。
  • 结果键将被索引,但值将是无序的并且可能出现多次。

经典 foreach:(演示)

$result = [];
for ($i = 0; $i < 8; ++$i) {
    $result[] = $array[array_rand($array)];
}
var_export($result);
//e.g.  [2, 5, 3, 1, 3, 5, 4, 2]

函数式 (演示)

var_export(
    array_map(fn() => $array[array_rand($array)], range(1, 8))
);
//e.g. [9, 2, 9, 9, 9, 5, 8, 8]

There are several ways to accomplish this task, but different approaches offer nuanced results. It makes no difference if the values are objects or any other data type. My demos will use a range of numbers from 1 to 9.

"shuffle & slice"

  • Concise and readable, but shuffle unnecessarily shuffles the full array despite needing only a subset.
  • Not a one-liner because shuffle() modifies by reference.
  • Result keys will be indexed and values will have a random order.

Code: (Demo)

shuffle($array);
var_export(array_slice($array, 0, 8));
//e.g.  [2, 8, 6, 9, 3, 5, 4, 1]

or

shuffle($array);
var_export(array_slice($array, -8));
//e.g.  [7, 3, 6, 8, 4, 1, 2, 5]


"array_rand (w/ count) & iterate"

  • Less concise, but still readable.
  • Can be written as a one-liner.
  • Result keys will be indexed and values will be ordered by their position in the input array.

Classic foreach: (Demo)

$result = [];
foreach (array_rand($array, 8) as $key) {
    $result[] = $array[$key];
}
var_export($result);
//e.g. [1, 2, 3, 4, 5, 6, 7, 8]

Functional-style one-liner: (Demo)

var_export(
    array_map(fn($k) => $array[$k], array_rand($array, 8))
);
//e.g. [1, 3, 4, 5, 6, 7, 8, 9]


"array_rand (w/ count) & flip & intersect_key"

  • Somewhat concise, less readable, calls 3 iterators instead of 2 like the aforementioned.
  • Can be written as a one-liner.
  • Result keys might not be indexed, but values will be ordered by their position in the input array.

Code: (Demo)

var_export(
    array_intersect_key($array, array_flip(array_rand($array, 8)))
);
//e.g. [1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6, 6 => 7, 7 => 8, 8 => 9]


"looped calls of array_rand"

  • Less concise, fairly readable, and makes iterated function calls.
  • Can be written as a one-liner, but calling range() is not super elegant.
  • Result keys will be indexed, but values will be unordered AND MAY OCCUR MORE THAN ONCE.

Classic foreach: (Demo)

$result = [];
for ($i = 0; $i < 8; ++$i) {
    $result[] = $array[array_rand($array)];
}
var_export($result);
//e.g.  [2, 5, 3, 1, 3, 5, 4, 2]

Functional-style (Demo)

var_export(
    array_map(fn() => $array[array_rand($array)], range(1, 8))
);
//e.g. [9, 2, 9, 9, 9, 5, 8, 8]
风渺 2024-09-24 06:54:42

又怎么样?:

$count = count($my_array);
for ($i = 0; $i < 8; $i++) {
  $x = rand(0, $count);
  $my_array[$x];
}

What about?:

$count = count($my_array);
for ($i = 0; $i < 8; $i++) {
  $x = rand(0, $count);
  $my_array[$x];
}
戏舞 2024-09-24 06:54:42

您可以使用此函数从数组中获取多个随机元素:

   function getRandomElements(array $array): array
    {
        $result = [];

        $count = count($array);
        for ($i = 0; $i < rand(0, $count); $i++) {
            $result[] = rand(0, $count);
        }
        $result = array_unique($result);
        sort($result);

        return $result;
    }

You can get multiple random elements from an array with this function:

   function getRandomElements(array $array): array
    {
        $result = [];

        $count = count($array);
        for ($i = 0; $i < rand(0, $count); $i++) {
            $result[] = rand(0, $count);
        }
        $result = array_unique($result);
        sort($result);

        return $result;
    }
尤怨 2024-09-24 06:54:42

您可以尝试使用此函数来重新混合您的对象
此函数获取您的对象并重新混合它,然后在直接编辑时以新顺序返回它

您可能还需要使用占位符作为所需内容的副本
重新混合,以防原始对象未被编辑。

/** randomize arrays and objects
 * @param mixed &$array an array taken to remix
 * @param int $swch - 1 if the first element is needed
 * @return mixed to store another copy of the remixed array
 */
function randomize(&$array, $swch = 0)
{
  // a placeholder for your array's first element
  if ($swch == 1) {
    $ST = $array[0];
    unset($array[0]);
  }
  // primary keys for the array or object to remix
  $k = array_keys($array);
  shuffle($k);

  /* note:- replace `$z[$v]` with `$z[]` incase you want to
   reorganize the array keys (numeral only) */
  foreach ($k as $v) {
    $z[$v] = $array[$v];
  }
  // restoring the remixed values
  $array = $z;
  if (isset($ST)) {
    array_unshift($array, $ST);
    unset($ST);
  }
  // launching a copy of the array incase needed
  return $array;
}

You may try using this function to remix your object:
this function takes your object and remixes it then returns it in a new order as it gets directly edited

you might also need to use a placeholder as a copy of the desired
remix in case the original object wasn't edited.

/** randomize arrays and objects
 * @param mixed &$array an array taken to remix
 * @param int $swch - 1 if the first element is needed
 * @return mixed to store another copy of the remixed array
 */
function randomize(&$array, $swch = 0)
{
  // a placeholder for your array's first element
  if ($swch == 1) {
    $ST = $array[0];
    unset($array[0]);
  }
  // primary keys for the array or object to remix
  $k = array_keys($array);
  shuffle($k);

  /* note:- replace `$z[$v]` with `$z[]` incase you want to
   reorganize the array keys (numeral only) */
  foreach ($k as $v) {
    $z[$v] = $array[$v];
  }
  // restoring the remixed values
  $array = $z;
  if (isset($ST)) {
    array_unshift($array, $ST);
    unset($ST);
  }
  // launching a copy of the array incase needed
  return $array;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文