在javascript中展平多级/嵌套数组

时间:2015-06-25 05:37:57

标签: javascript arrays concat

我试图理解这段代码如何平整多层/嵌套数组

任何人都可以帮忙详细说明吗?感谢

var flatten = function(a, shallow,r){
  if(!r){ r = []}     //what does the exclamation mark mean here?...

if (shallow) {
  return r.concat.apply(r,a);  //I can't find what's .apply for concat method
  }

   for(var i=0; i<a.length; i++){
        if(a[i].constructor == Array){
            flatten(a[i],shallow,r);
        }else{
            r.push(a[i]);
        }
    }
    return r;
}

alert(flatten([1, [2], [3, [[4]]],[5,6]]));

3 个答案:

答案 0 :(得分:5)

有趣的是,在示例中没有达到代码的浅部分。

更新

我认为这个功能很难理解。这是一个可能更容易阅读的替代品。

function flatten(arr) {

  var flatArray = [];

  function pushLoop(a) {
    var len = a.length;
    var i=0;
    for (i; i < len; i++) {
      if (a[i] && a[i].constructor == Array) {
        pushLoop(a[i]);
      } else {
        flatArray.push(a[i]);
      }
    }
  }

  pushLoop(arr);
  return flatArray;
}

原始snippit

&#13;
&#13;
var flatten = function(a, shallow, r) {

  // if r does not exist create.
  if (!r) {
    r = []
  }

  // if shallow exists concat the arrays
  if (shallow) {

    // concat joins two or more arrays as paramenters.
    // The prototype apply allows us to define the parameters
    // as an array.  Esentially concat the arrays in array a.
    return r.concat.apply(r, a);
  }


  for (var i = 0; i < a.length; i++) {
    // Only flatten items that are arrays and push everything
    // else to the end.
    if (a[i].constructor == Array) {
      flatten(a[i], shallow, r);
    } else {
      r.push(a[i]);
    }
  }
  return r;
}

var output = document.getElementById("output");

var arr = (flatten([1, [2],
  [3, [
    [4]
  ]],
  [5, 6]
]));

output.innerHTML = JSON.stringify(arr);
&#13;
<div id="output"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

!r是“不是r”中的否定。这意味着如果r = false,r = null或r = undefined,则if状态意味着为真。

.apply()是javascript中所有函数的成员。它允许您使用与其所在的函数不同的“this”范围来调用函数。请查看此函数:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

答案 2 :(得分:0)

关于申请

行返回r.concat.apply(r,a)具有误导性。

他们本可以使用[] .concat.apply(r,a)。 'apply'是在'function'类型的每个对象上定义的方法(typeof o ==='function',基本上是任何可调用对象),它执行函数,'this'绑定到第一个参数,并且数组中的参数通过作为第二个论点。

所以我们假设我们有一个函数'f'。

    function f(a,b,c) {
      this.x = a + b + c;
    }

这两个代码块都调用f,其中=== objInstance,并且在运行两个块之后,objInstance.x = 6。

    var Obj = function() {};
    Obj.prototype.f = f;
    var objInstance = new Obj();
    objInstance.f(1,2,3);

    var Obj = function () {};
    var objInstance = new Obj();
    f.apply(objInstance, [1,2,3]);

所以[] .concat.apply(r,a)相当于在对象r上应用参数a的[] .concat。它将a中的每个数组连接到数组r。