【问题标题】:How to output different values from an array如何从数组中输出不同的值
【发布时间】:2020-03-31 01:40:23
【问题描述】:

我的代码有问题。我想做的是在数组被调用时从数组中删除一个项目,这意味着我希望每个输出都不同。我想用它来旋转代理,阵列中有超过 150 个代理。这是我的代码示例。


for ( $i = 1; $i < 2; $i++ )
{
  // If the array_history is empty, re-populate it.
  if (empty($array_history))
    $array_history = $array;

  // Select a random key.
  $key = array_rand($array_history, 1);

  // Save the record in $selected.
  $selected = $array_history[$key];

  // Remove the key/pair from the array.
  unset($array_history[$key]);

  // Echo the selected value.
  echo $selected; 
}

我该怎么做,或者 for 循环不适合这个?提前致谢。

【问题讨论】:

  • 不清楚您要达到的目标。请提供一些示例数据以及您想要的输出。看看How to Ask 和edit 你的问题。
  • 我已经编辑了我的问题并解释了更多,你能帮忙

标签: php arrays for-loop variables arraylist


【解决方案1】:

我稍微改变了一点,对我来说,它读取为代码,它将选择一个项目,随机选择一个,丢弃该项目,然后再次选择,直到一个都没有。如果没有剩余,则复制原始数组并重新开始。

目前您的代码循环一次。我在这里将循环扩展到 4 次迭代。并且在每次随机选择时,将该随机密钥存储在历史数组中。然后,您可以稍后在代码中参考该历史记录。

<?php
$array = 
[
    'beatle' => 'John',
    'stone' => 'Mick',
    'floyd' => 'Syd'
];

for ($history = [], $i = 1; $i < 5; $i++)
{
  if (empty($buffer))
    $buffer = $array;

  $key = array_rand($buffer, 1);
  $history[] = $key;

  echo $buffer[$key], "\n";

  unset($buffer[$key]);
}

var_export($history);

示例输出:

Syd
Mick
John
Syd
array (
  0 => 'floyd',
  1 => 'stone',
  2 => 'beatle',
  3 => 'floyd',
)

参考上面的历史数组:

echo $array[$history[3]];

将输出Syd。

将上述内容改编并封装在一个类中。这将做同样的事情(但不存储选择的历史),从数组中随机取出一个项目并删除,直到数组中没有更多项目,然后补充列表等等:

class RandomProxies
{
    const PROXIES = 
    [
        'proxy1' => 'foo.example.com',
        'proxy2' => 'bar.example.com',
        'proxy3' => 'baz.example.com',
    ];

    private $buffer;

    public function getProxy() {
        if (empty($this->buffer))
            $this->buffer = self::PROXIES;
        $key = array_rand($this->buffer);
        $proxy = self::PROXIES[$key];
        unset($this->buffer[$key]);

        return $proxy;
    }
}

$randomiser = new RandomProxies;

foreach(range(1,4) as $n) {
    echo $randomiser->getProxy(), "\n";
}

示例输出:

foo.example.com
baz.example.com
bar.example.com
foo.example.com

【讨论】:

  • 感谢您的回答。我想使用代码来旋转代理,我想要它做的是在数组中选择代理,随机选择一个,丢弃列表,然后再次选择,直到列表中没有更多的代理。如果没有剩余,请复制原始数组并重新开始。问题是,我得到了重复的输出。
  • @Xternet 这几乎就是代码的作用。我不确定你遇到了什么问题?我已经在上面封装了我的改编代码。也许这就是你所追求的。请注意,您可能会在列表补充时得到重复。
【解决方案2】:

这对于generator 来说似乎是一个不错的应用程序。这个接受一个代理地址数组并以随机顺序循环数组,每次重新开始循环时都会对数组进行洗牌。

function get_proxy($proxies) {
    $i = 0;
    $len = count($proxies);
    while (true) {
        if ($i == 0) shuffle($proxies);
        yield $proxies[$i];
        $i = ($i + 1) % $len;
    }
}

要使用它,你可以这样做:

$proxies = array('10.0.0.4', '192.168.0.1', '10.1.0.1');
$i = 0;
foreach (get_proxy($proxies) as $proxy) {
    echo "$proxy\n";
    $i++;
    // stop otherwise infinite loop
    if ($i == 9) break;
}

请注意,由于生成器中有一个无限循环,外部foreach 循环也将是无限的,因此需要一种方法来打破(在这种情况下我使用了一个简单的计数器)。

上述代码的示例输出:

10.1.0.1
10.0.0.4
192.168.0.1
192.168.0.1
10.1.0.1
10.0.0.4
10.1.0.1
192.168.0.1
10.0.0.4

Demo on 3v4l.org

如果生成器不适合您的代码结构,您可以使用带有静态变量的函数在每次调用时返回一个新代理:

$proxies = array('10.0.0.4', '192.168.0.1', '10.1.0.1');

function get_proxy($proxies) {
    static $i = 0, $keys;
    if (!isset($keys)) $keys = array_keys($proxies);
    if ($i == 0) shuffle($keys);
    $proxy = $proxies[$keys[$i]];
    $i = ($i + 1) % count($keys);
    return $proxy;
}

for ($i= 0; $i < 9; $i++) {
    echo get_proxy($proxies) . "\n";
}

此代码的示例输出:

10.1.0.1
10.0.0.4
192.168.0.1
192.168.0.1
10.1.0.1
10.0.0.4
10.0.0.4
192.168.0.1
10.1.0.1

Demo on 3v4l.org

【讨论】:

  • @Xternet 不确定您是否看到了原始答案,但如果这不适合我已经更新了一个不同的函数,它可以以更灵活的方式给出相同的结果(它可以被称为作为一个函数,不像生成器)。
  • 感谢您的回答,我使用了带有静态变量的函数。
  • @Xternet 我很高兴其中一位为您工作。这是一个有趣的问题。
  • 我在 CLI 中遇到了这个错误,尽管参数是正确的 Warning: array_keys() expects parameter 1 to be array, null given in /storage/emulated/0/hyperlook/hyperlooko.php on line 219 Warning: shuffle() expects parameter 1 to be array, null given in /storage/emulated/0/hyperlook/hyperlooko.php on line 220 Warning: count(): Parameter must be an array or an object that implements Countable in /storage/emulated/0/hyperlook/hyperlooko.php on line 222
  • 我需要把代理数组放在函数里面吗?
【解决方案3】:

您想要做的是将访问分散到 150 个代理上。在这种情况下,实际上没有必要随机进行。你可以遍历数组。

<?php 

$array = [0, 1, 2, 3, 4, 5, 6];

for ( $i = 1; $i < 20; $i++ )
{
    echo getNext($array) . '<br>';
}

function getNext (&$array) {
  $e = next($array); // Every time next element is selected. Each output is different.
  if ($e)
    return $e;
  else 
    return reset($array);
}

?>

【讨论】:

  • 感谢您的回答。我想要实现的是只获得一个输出,但每次都应该不同
  • 通过调用 getNext($array) 你得到一个结果,每次都不一样。
  • 我为你投了赞成票,但我不知道为什么它没有显示
【解决方案4】:

当你在php中定义一个数组比如

<?php
$alphabet = array(a, b, c)
?> 

您试图在数组中查找元素。元素列表总是从 0 开始计数。所以调用单个元素从 0 开始从左到右计数。

<?php
#a
echo $alphabet[0];

#b
echo $alphabet[1];

#c
echo $alphabet[2]; 

?> 

上面的部分应该产生 abc 的结果,因为没有中断。

对于遍历整个数组并运行检查、错误分析甚至数学作为示例,For 循环非常方便。

【讨论】:

  • 我已经知道了。在原始代码中,我在数组中有超过 150 个元素。正如您在代码中看到的那样,我想做的是在调用列表时从列表中删除一个项目,我希望每个输出都不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-22
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多