javascript中递归复制二维数组的算法

Algorithm for copying 2 dimensional array in javascript recursively

本文关键字:算法 二维数组 复制 递归 javascript      更新时间:2023-09-26

我想找到这个算法,用于将二维数组reffering复制到不同的堆对象。例如,如果我有。。。

 var result = [[8,2,5],[3],[8,5,2],[0]];
    var resultCopy = copyArray(result);
    resultCopy[2][0] = 9;

然后alert(result[2][0]);。。。。。。应该是8而不是9!

我只有这个,但它不起作用,我似乎可以在其他地方找到答案:

  function copyArray(array){
    result;
    array.length==0?return result;
    for(var i=0;i!=array.length;i++){
        if(array[i] instanceof Array){
            return result.push(copyArray(array[i].slice(0)));
        } else {
            return result.push(array)
            }
        }
    }

如果您有幸拥有NetScape浏览器衍生产品(FF等)

resultCopy = eval  (  uneval( result  )   );

resultCopy = eval  (  result  .   toSource(  )   );

否则使用(这有严重的限制,但满足OP条件):

resultCopy = eval( "[ [" + result  .  join("], 'n[")   + "] ]" );

eval函数是"内置的",隐藏了其算法的递归性质。

如果重写(即递归)是神圣不可侵犯的,那么以下内容是非常虔诚的,没有迭代语句,并且完全递归,直到每个元素都不是数组。(即当元素是数组或在数组中时发生递归)。给定一个数组,如果它是空的,那么它的副本将是空的array.length < 1 ? [ ]。如果不从数组中提取元素,则将数组缩减为需要进一步处理的较小元素。这是递归归约步骤RAffle ( array . pop( ), arbitArrayCopy ( array ) )。新阵列中填充了移除nuRA . push ( ... )element。如果element恰好是一个数组,则对其进行进一步处理,即重新诅咒element instanceof Array ? arbitArrayCopy ( element )。该算法是破坏性的,并且原始数组是无瑕疵的,所以恢复它:array . push ( element )

 function arbitArrayCopy ( array )  { 
  /* copies any nD array structure and primitive array elements  but 
                  complex compound object array elements are referenced and not copied   */
       return array.length < 1   ?   [ ]   : RAffle ( array . pop( ),  arbitArrayCopy ( array )  )  ;
       function RAffle ( element, nuRA )  {
               nuRA  .  push ( element instanceof Array ?  arbitArrayCopy  ( element  )   :  element  ) ;
               array   .  push ( element )  ;
               return  nuRA
       }
  }

测试:

data:text/html;charset=utf-8,<html>
<!-- this is a scriple or scURIple which codes generic URI's of arbitrary schema
               -  javascript: schema specific scriples/scURIples are known as scriplets or bookmarklets -->
<script>
javascript:
function RAcopy ( array ) {  return array.length < 1   ?   [ ]   :  RAffle( array . pop( ),  RAcopy ( array ) ) ;
    function RAffle ( element, nuRA )  {
        nuRA  .  push ( element instanceof Array ?  RAcopy  ( element  )   :  element  ) ;
        array   .  push ( element )  ;                                                   return  nuRA
}   }
result = [[8,2,5],[3],[8,5,2],[0]];
RAdup = RAcopy ( resultCopy = eval( "[ [" + result  .  join("], 'n[")   + "] ]" )  )  ;
resultCopy[2][0] = 9;    resultCopy[3] = [10,11,12];   RAdup[1]=[ 42, 33, 24 ];    delete RAdup[3];
alert  (  [    "Test environment:'n " + window.navigator.userAgent, 
                    "RAdup ='n"       + RAdup         . join("], 'n[") , 
                    "resultCopy ='n" + resultCopy   . join("], 'n[") , 
                    "result ='n"         + result            . join("], 'n[")                      ]  .  join("'n ..................... 'n")   );
</script></html>

(注意:scURI由于并发URI、javascript和HTML语法的语言多样性而受到多语言的挑战,但对于即时模式的地址栏拖放执行来说很方便-它们的语法的共生协同作用往往会屈服于寄生-幸运的是,这里的力量是一致的-特别是HTML <script>有意包含javascript:标签通过javascript:schema/protocol使脚本成为一个有效的URI字符串,所有这些都嵌入到更大的URI数据中:scheme scURIple-因此数据:URI scURIple编码有效的HTML,该HTML编码有效的javascript,该javascript编码有效的javascript:URI字符串-当脚本生成其他scURI,甚至它自己时,情况会变得非常奇怪)

测试结果:

Test environment: 
 Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4
                                                                                                                            (Splashtop-v1.2.17.0)
 ..................... 
RAdup =
8,2,5], 
[42,33,24], 
[8,5,2], 
[
 ..................... 
resultCopy =
8,2,5], 
[3], 
[9,5,2], 
[10,11,12
 ..................... 
result =
8,2,5], 
[3], 
[8,5,2], 
[0

链接:javascript中递归复制二维数组的算法

此代码中有几个错误:

  • 在函数内部声明result时缺少var关键字。这将在全局范围内创建/修改变量;

  • 无效的内联if语法(缺少用于else的:)。在这种情况下,我建议使用普通的if语法。

  • 您将在所有路径中返回for内部的数组。这将使它返回result变量,并在循环的第一次迭代中停止执行,从而生成一个只有一个元素的数组。

  • for语句中else中缺少[i]。您可能想要从数组中复制一个元素,而不是完全复制。

你正在寻找的功能可能是:

function copyArray(array) {
    var result = []; // creates an result array inside your function scope
    if (array.length == 0)
        return result; // return this empty array in case the input array is also empty
    for (var i = 0; i != array.length; i++) {
        if (array[i] instanceof Array) {
            result.push(copyArray(array[i].slice(0))); // call the function recursively if the element is an array
        } else {
            result.push(array[i]); // copy the element if it is not an array (going to use reference if it's an object)
        }
    }
    return result; // returns the resulting array
}

请记住,这不会复制对象,而是保留对它们的引用。如果你也想解析它们,可以看看StackOverflow中的这个问题:如何正确地克隆JavaScript对象?