假设我有
$a = [1,4,5,8,9,...];
包含大量不连续数字,
$p = [
1 => [...],
3 => [...],
8 => [...],
10 => [...],
...
];
包含已停止索引的数组。
我需要删除$a
中$p
中具有相应索引的所有数字...等待...而不使用任何函数。
有可能吗?如果有,怎么样?如果不是,那么解决这个问题的最佳方式是什么(以挂钟方式)?
答案 0 :(得分:1)
当然,这是可能的:
$filtered_array = [];
foreach ($a as $index => $value) {
foreach ($p as $key => $sub_array) {
if ($key == $value) {
// this $value of $a corresponds with an existing index in $p, so
// do NOT add it to our $filtered_array but move on to the next
// value of $a
continue 2;
}
}
$filtered_array[$index] = $value;
}
当然这会非常慢,因为$a
中的每个条目都不在$p
中,您需要遍历整个$p
数组才能发现它不是'在那里。更有效的解决方案是利用当您尝试访问不存在的数组索引时抛出的PHP OutOfBoundsException
:
$filtered_array = [];
foreach ($a as $index => $value) {
try {
$p[$value];
} except (OutOfBoundsException $e) {
// $value does not exist as an index of $p
$filtered_array[$index] = $value;
}
}
如果您不需要保留数组键,性能可能会有所提高(在这种情况下您不需要$index
,这会为$a
中的每个项目保存内存分配),但我认为这种差异可以忽略不计。
使用某些数组函数将更高效:
$filtered_array = [];
foreach ($a as $index => $value) {
if (!array_key_exists($value, $p)) {
$filtered_array[$index] = $value;
}
}
由于您不需要通过PHP错误处理的try / catch机制,因此速度会更快。
如果您允许自己使用unset()
删除$p
中 的值,可能会更快,因此您无需创建新数组但可以改为$a
。从您的代码示例和短数组语法,我假设您使用PHP 7.由于PHP 7不再使用foreach
的内部数组指针,您可以在迭代时安全地unset()
项。如果你在PHP 5上运行,你仍然可以这样做但是你冒着foreach
跳过某些项目的风险。
foreach ($a as $index => $value) {
if (array_key_exists($value, $p)) {
unset($a[$index]);
}
}
这样做可以减少第二个(可能很大的)阵列闲置的内存开销。
但是既然你现在已经打破了自己的“无功能”规则,你也可以一直使用array_filter
(虽然这不会修改现有的数组,而是构建一个新的数组,这会降低非常大的数组的性能):
$filtered_array = array_filter($a, function($value) use ($p) {
return !array_key_exists($value, $p);
});
答案 1 :(得分:-2)
所以我回答了我自己的问题,人们太忙了,不能用贬低和幼稚的评论说'#34;它不可能","是它的作业"。不,这不是功课,我只是希望在这里有一点帮助(你知道,就像在社区)。
我试图实现的目标,删除在另一个数组中具有索引的数组中的每个数字(都具有已停止的值)而不使用任何函数:
// temporary $a
$a_temp = [];
foreach ($a as $avalue) {
foreach ($p as $k => $v) {
// if iterator $a is in the $p (we disregard)
if ($avalue === $k) {
continue 2;
}
}
$a_temp[] = $avalue;
}
$a = $a_temp;
(如果你看到上述功能,请给我发电子邮件)
这里有一些测试。
/********************************
* initialize fake data
********************************/
$p = [];
for ($i = 0; $i < 10; ++$i) {
$p[rand(0, 500)] = null;
}
for ($j = 0; $j < 1000; ++$j) {
$a[rand(0, 500)] = null;
}
$a = array_keys($a);
/********************************
* first test (without functions)
********************************/
$start = microtime(true);
for ($i = 0; $i < 9999; ++$i) {
$a_temp = [];
foreach ($a as $avalue) {
foreach ($p as $k => $v) {
if ($avalue === $k) {
continue 2;
}
}
$a_temp[] = $avalue;
}
}
$firstTestExecTime = (microtime(true) - $start);
// average time : 8s6757750511169
/********************************
* second test, with functions
********************************/
$start = microtime(true);
for ($i = 0; $i < 9999; ++$i) {
$a_temp = [];
foreach ($a as $avalue) {
if (!array_key_exists($avalue, $p)) {
$a_temp[] = $avalue;
}
}
}
$secondTestExecTime = (microtime(true) - $start);
// average time : 5.1003220081329
/********************************
* printing results
********************************/
printf('first test execution time : %s', $firstTestExecTime);
printf('second test execution time : %s', $secondTestExecTime);
有时不建议使用包含大量数据的函数,但在这种情况下,array_search
似乎比尝试生成本机代码具有更好的性能。