PHP的array_map和array_filter返回引用而不是新的数组。

23 浏览
0 Comments

PHP的array_map和array_filter返回引用而不是新的数组。

我有一个对象数组。我知道对象通过“引用”进行赋值,而数组通过“值”进行赋值。但是当我赋值数组时,数组的每个元素都引用了对象,所以当我在任何一个数组中修改对象时,另一个数组中的对象也会发生变化。

有没有一种简单的方法可以克隆一个数组,还是我必须循环遍历它来克隆每个对象?

0
0 Comments

PHP中的array_map和array_filter函数可以用于对数组进行处理,并返回处理后的新数组。然而,有时候我们希望返回的不是新数组,而是对原数组中的对象进行深拷贝(deep copy)。下面是一个关于这个的问题。

讨论中提到,当我们复制一个数组时,已经引用的对象会被复制到新数组中。但是,如果我们希望在创建新数组时对被引用的对象进行深拷贝,以便得到两个不同但相似的对象数组,就需要特别处理。讨论中给出了一种使用循环的解决方法,代码如下:

$new = array();
foreach ($old as $k => $v) {
    $new[$k] = clone $v;
}

这段代码使用了clone关键字对对象进行深拷贝,从而得到了一个新的数组。

讨论中还提到,clone操作实际上是对对象进行浅拷贝(shallow copy),而不是深拷贝(deep copy)。对于是否进行深拷贝,取决于对象的具体实现。如果对象中包含对其他对象的引用,并且没有实现适当的__clone方法,那么拷贝的结果仍然是浅拷贝。换句话说,如果你要拷贝的对象的开发者实现得正确,那么拷贝结果就是深拷贝。

讨论中还提到,clone操作并不总是能创建独立的拷贝。具体取决于对象的实现。PHP官方文档中提到,如果对象的属性是对其他变量的引用,那么拷贝后的属性仍然是引用。

对于原数组中的对象进行深拷贝,可以使用循环结合clone关键字来实现。但需要注意,clone操作并不总是能创建独立的拷贝,具体取决于对象的实现。

0
0 Comments

问题的出现原因是当使用array_map和array_filter函数时,它们会返回一个新的数组,而不是原始数组的引用。因此,在对数组中的对象进行操作时,可能会出现引用相同对象的问题。

解决方法是使用一个名为array_copy的函数,该函数可以对数组进行深拷贝,避免引用相同对象。该函数通过遍历数组的每个元素,如果元素是数组,则递归调用array_copy函数进行拷贝,如果元素是对象,则使用clone关键字进行拷贝,否则直接将元素赋值给新数组。最后,返回新的数组。

下面是array_copy函数的代码示例:

function array_copy($arr) {
    $newArray = array();
    foreach($arr as $key => $value) {
        if(is_array($value)) $newArray[$key] = array_copy($value);
        else if(is_object($value)) $newArray[$key] = clone $value;
        else $newArray[$key] = $value;
    }
    return $newArray;
}

这个函数简单而有效,可以作为静态函数使用。它可以解决在使用array_map和array_filter函数时可能遇到的引用相同对象的问题。

另外,有用户在stackoverflow上偶然发现了类似的array_copy函数,并且不经意间使用了这个函数。这个函数的链接是:stackoverflow.com/a/17729234/1134804。用户在这个页面上多次浏览,但总是忽略了这个函数的答案。直到现在才意识到这个函数和自己的函数几乎完全相同。

通过使用array_copy函数,可以避免在使用array_map和array_filter函数时出现引用相同对象的问题。这个函数是一个有用的工具,可以确保每次操作数组时都得到一个新的数组,而不是原始数组的引用。

0
0 Comments

问题出现的原因是因为在使用array_map和array_filter函数时,它们返回的是数组的引用而不是新的数组。这导致在对返回的数组进行操作时,原始数组也会被修改。

解决方法是使用array_merge函数来创建原始数组的副本。例如,$array = array_merge(array(), $myArray)可以创建一个新的数组,其中包含了$myArray的所有元素。这样可以避免对原始数组的修改。

另一种解决方法是使用强制类型转换。例如,$array = (array)$myArray可以将$myArray转换为一个新的数组。这样也可以避免对原始数组的修改。

总结起来,为了避免使用array_map和array_filter函数返回的数组引用导致对原始数组的修改,可以使用array_merge函数或强制类型转换来创建数组的副本。这样可以确保对返回的数组进行操作时不会修改原始数组。

0