'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

// 兼容ES7的includes
if (!window.Array.prototype.includes) {
  window.Array.prototype.includes = function (searchElement) {
    return this.some(function (el) {
      return el === searchElement;
    });
  };
}

// 幂集 如:[1,2],返回[[1],[2],[1,2]]
window.Array.prototype.powerset = function () {
  var ps = [[]];
  for (var i = 0; i < this.length; i++) {
    for (var j = 0, len = ps.length; j < len; j++) {
      ps.push(ps[j].concat(this[i]));
    }
  }
  return ps;
};

// 二维数组转为一维数组
window.Array.prototype.toOneColumn = function () {
  var reg = /[\d\.]+\,([\d\.]+)/g; // eslint-disable-line
  return this.join(',').replace(reg, '$1').split(',');
};

// 包含，支持传数组包含数组
window.Array.prototype.contains = function (arg) {
  if (toString.call(arg) !== '[object Array]') {
    return this.indexOf(arg) > -1;
  }
  return this.filter(function (elem) {
    return arg.indexOf(elem) > -1;
  }).length === arg.length;
};

// 比较两个数组是否相同, 比较不了包含{x: 20}的数组
if (window.Array.prototype.equals) {
  console.warn('覆盖现有的window.Array.prototype.equals。 可能的原因：新的API定义了方法，存在框架冲突，或者在代码中包含了双重包含。');
}
window.Array.prototype.equals = function (array) {
  if (!array) return false;

  // 比较长度可以节省很多时间
  if (this.length !== array.length) return false;

  for (var i = 0; i < this.length; i++) {
    // 检查是否有嵌套的数组
    if (this[i] instanceof Array && array[i] instanceof Array) {
      // 递归到嵌套数组中
      if (!this[i].equals(array[i])) return false;
    }
    // 检查是否有JSON数据,只比较一层
    else if (this[i] instanceof Object && array[i] instanceof Object) {
        for (var n in this[i]) {
          if (this[i][n] !== array[i][n]) return false;
        }
      } else if (this[i] !== array[i]) {
        // 警告 - 两个不同的对象实例永远不会相同：{x：20}!= {x：20}
        return false;
      }
  }
  return true;
};
// 从for-in循环隐藏方法
Object.defineProperty(window.Array.prototype, "equals", { enumerable: false });

// 判断数组中是否有重复数据,只能比较数字字符串
window.Array.prototype.isRepeatArray = function () {
  var arrStr = this.join(',') + ',';
  for (var _iterator = this, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
    var _ref;

    if (_isArray) {
      if (_i >= _iterator.length) break;
      _ref = _iterator[_i++];
    } else {
      _i = _iterator.next();
      if (_i.done) break;
      _ref = _i.value;
    }

    var item = _ref;

    if (arrStr.replace(item + ',', '').indexOf(item + ',') >= 0) return true;
  }
  return false;
};
// 移除数组json中的项
window.Array.prototype.removeProperties = function (properties) {
  for (var _iterator2 = this, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
    var _ref2;

    if (_isArray2) {
      if (_i2 >= _iterator2.length) break;
      _ref2 = _iterator2[_i2++];
    } else {
      _i2 = _iterator2.next();
      if (_i2.done) break;
      _ref2 = _i2.value;
    }

    var item = _ref2;

    for (var n in item) {
      for (var _iterator3 = properties, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
        var _ref3;

        if (_isArray3) {
          if (_i3 >= _iterator3.length) break;
          _ref3 = _iterator3[_i3++];
        } else {
          _i3 = _iterator3.next();
          if (_i3.done) break;
          _ref3 = _i3.value;
        }

        var property = _ref3;

        if (n === property) delete item[n];
      }
    }
  }
  return this;
};
// 将数组中的项都转成字符串
window.Array.prototype.toStringOption = function () {
  return this.map(function (item) {
    if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object' || typeof item === 'function') return JSON.stringify(item);
    return item;
  });
};
// 获取相同值的索引, 例如: [1,1,2,2] 返回: [[0, 1], [2, 3]]
window.Array.prototype.sameIndexs = function () {
  var arr = this;
  // 去重得出分组值
  var group = [].concat(new Set(arr));
  // 归类, 得到重复索引, [[重复索引], []]
  var groupIndexs = [];
  for (var _iterator4 = group, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
    var _ref4;

    if (_isArray4) {
      if (_i4 >= _iterator4.length) break;
      _ref4 = _iterator4[_i4++];
    } else {
      _i4 = _iterator4.next();
      if (_i4.done) break;
      _ref4 = _i4.value;
    }

    var groupValue = _ref4;

    var subGroupIndexs = [];
    for (var _iterator5 = arr.entries(), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
      var _ref6;

      if (_isArray5) {
        if (_i5 >= _iterator5.length) break;
        _ref6 = _iterator5[_i5++];
      } else {
        _i5 = _iterator5.next();
        if (_i5.done) break;
        _ref6 = _i5.value;
      }

      var _ref5 = _ref6;
      var index = _ref5[0];
      var arrValue = _ref5[1];

      if (groupValue === arrValue) {
        subGroupIndexs.push(index);
      }
    }
    groupIndexs.push(subGroupIndexs);
  }
  return groupIndexs;
};

/* -----------------------------------------------------
  树数据扁平化, 将树的children拉平
  @格式 [{id: '', name: '', children: {}}]
  @return [{id: '', name: '', parentid: ''}, {id: '', name: '', parentid: ''}]
 ----------------------------------------------------- */
window.Array.prototype.flattenTree = function (parentIdName, nodeIdName) {
  var list = this;
  if (!Array.isArray(list) || !list.length) return list;
  return _buildTreeToFlatten(list, parentIdName, nodeIdName);
};
function _buildTreeToFlatten(list, parentIdName, nodeIdName) {
  // 扁平化, 将children拉平
  var tree = [];
  var temp = []; // 用于存储children
  // 先将第一层节点放入temp
  for (var i = 0; i < list.length; i++) {
    temp.push(list[i]);
  }
  while (temp.length) {
    // 取出一项, 并移除此项
    var item = temp.shift();
    // 此项children合并到temp
    if (item.children && item.children.length) {
      // 添加parentid
      for (var c = 0; c < item.children.length; c++) {
        item.children[c][parentIdName || 'parentid'] = item[nodeIdName || 'id'];
      }
      temp = item.children.concat(temp);
    } else {
      item.isLeaf = true;
    }
    // 删除此项children
    delete item.children;
    // 添加此项到tree
    tree.push(item);
  }
  return tree;
}

// 取出无父节点的顶层数据, 即[{id: '', name: '', parentid: '-1' 或没有parentid}]
window.Array.prototype.getFlattenTreeRoots = function (parentIdName, nodeIdName) {
  var list = this;
  var roots = [];
  // 取出顶层数据(没有parentid或者parentid===-1)
  list.forEach(function (item) {
    if (!item[parentIdName || 'parentid'] || String(item[parentIdName || 'parentid']) === '-1') roots.push(item);
  });
  return roots;
};

// 根据id, 取出此id的下级节点数据, 即[{id: '', name: '', parentid: ''}]
window.Array.prototype.getFlattenTreeChildren = function (id, parentIdName) {
  var list = this;
  var children = [];
  for (var i = 0, child; child = list[i++];) {
    // eslint-disable-line
    if (id && child[parentIdName || 'parentid'] === id.toString()) {
      children.push(child);
    }
  }
  return children;
};

// 根据id, 取出此id的后代节点数据, 即[{id: '', name: '', parentid: ''}]
window.Array.prototype.getFlattenTreeDescendants = function (id, parentIdName, nodeIdName) {
  var list = this;
  var descendants = [];
  function buildChildren(list, id) {
    for (var i = 0, item; item = list[i++];) {
      // eslint-disable-line
      if (id && item[parentIdName || 'parentid'] === id.toString()) {
        descendants.push(item);
        buildChildren(list, item[nodeIdName || 'id']);
      }
    }
  }
  buildChildren(list, id);
  return descendants;
};

// 根据id, 取出此id的上级节点数据, 即[{id: '', name: '', parentid: ''}]
window.Array.prototype.getFlattenTreeParent = function (parentId, parentIdName, nodeIdName) {
  var list = this;
  var parents = [];
  for (var i = 0, node; node = list[i++];) {
    // eslint-disable-line
    if (parentId && node[nodeIdName || 'id'] === parentId.toString()) {
      parents.push(node);
    }
  }
  return parents;
};

// 根据id, 取出此id的前代节点数据, 即[{id: '', name: '', parentid: ''}]
window.Array.prototype.getFlattenTreePredecessors = function (parentId, parentIdName, nodeIdName) {
  var list = this;
  var predecessors = [];
  function buildParent(list, parentId) {
    for (var i = 0, node; node = list[i++];) {
      // eslint-disable-line
      if (parentId && node[nodeIdName || 'id'] === parentId.toString()) {
        predecessors.push(node);
        buildParent(list, node[parentIdName || 'parentid']);
      }
    }
  }
  buildParent(list, parentId);
  return predecessors;
};

// 根据id, 取出此id节点的数据, 即{id: '', name: '', parentid: ''}
window.Array.prototype.getFlattenTreeNode = function (id, parentIdName, nodeIdName) {
  var list = this;
  var item = list.filter(function (option) {
    if (option[nodeIdName || 'id'] === id) return true;
    return false;
  });
  if (item && item.length > 0) {
    item = item[0];
  }
  return item;
};

/* -----------------------------------------------------
  树数据深度化, 将树的parentid深度为children, 必须有id和parentid
  @格式 [{id: '', name: '', parentid: ''}, {id: '', name: '', parentid: ''}]
  @return [{id: '', name: '', children: {}}]
 ----------------------------------------------------- */
window.Array.prototype.deepTree = function (parentIdName, nodeIdName) {
  var list = this;
  if (!Array.isArray(list) || !list.length) return list;

  // 深度化, 修改trees
  function _buildTreeToDeep(item) {
    var children = list.getFlattenTreeChildren(item[nodeIdName || 'id'], parentIdName, nodeIdName);
    if (children && children.length) {
      if (item.children) {
        item.children.push(children);
      } else {
        item.children = children;
      }
      for (var i = 0, child; child = children[i++];) {
        // eslint-disable-line
        _buildTreeToDeep(child);
      }
    } else {
      item.isLeaf = true;
    }
  }
  var trees = list.getFlattenTreeRoots(parentIdName, nodeIdName);
  for (var i = 0, tree; tree = trees[i++];) {
    // eslint-disable-line
    _buildTreeToDeep(tree);
  }
  return trees;
};

// 根据id, 取出此id节点的数据, 即{id: '', name: '', parentid: ''}
window.Array.prototype.getDeepTreeNode = function (id, parentIdName, nodeIdName) {
  var list = Object.clone(this);
  var temp = []; // 用于存储children
  // 先将第一层节点放入temp
  for (var i = 0; i < list.length; i++) {
    temp.push(list[i]);
  }
  while (temp.length) {
    // 取出一项, 并移除此项
    var item = temp.shift();
    if (item[nodeIdName || 'id'] === id) return item;
    // 此项children合并到temp
    if (item.children && item.children.length) {
      // 添加parentid
      for (var c = 0; c < item.children.length; c++) {
        item.children[c][parentIdName || 'parentid'] = item[nodeIdName || 'id'];
      }
      temp = item.children.concat(temp);
    }
    // 删除此项children
    delete item.children;
  }
  return {};
};