Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/432.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 合并/展平一组数组_Javascript_Arrays_Flatten - Fatal编程技术网

Javascript 合并/展平一组数组

Javascript 合并/展平一组数组,javascript,arrays,flatten,Javascript,Arrays,Flatten,我有一个JavaScript数组,如: [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]] 如何将单独的内部阵列合并为一个类似于: ["$6", "$12", "$25", ...] 您可以使用concat合并数组: var数组=[ ["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"] ]; var merged=[].concat.apply([]

我有一个JavaScript数组,如:

[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]
如何将单独的内部阵列合并为一个类似于:

["$6", "$12", "$25", ...]

您可以使用
concat
合并数组:

var数组=[
["$6"],
["$12"],
["$25"],
["$25"],
["$18"],
["$22"],
["$10"]
];
var merged=[].concat.apply([],数组);

console.log(合并)要展平单个元素数组的数组,您不需要导入库,简单循环是最简单的解决方案:

for (var i = 0; i < a.length; i++) {
  a[i] = a[i][0];
}
for(变量i=0;i

反对者:请阅读这个问题,不要反对,因为它不适合你完全不同的问题。此解决方案对于所问问题来说是最快和最简单的。

这并不难,只需迭代数组并合并它们:

var result = [], input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"]];

for (var i = 0; i < input.length; ++i) {
    result = result.concat(input[i]);
}
var结果=[],输入=[“$6”],[“$12”],[“$25”],[“$25”],[“$18”];
对于(变量i=0;i
您可以使用:


如果只有包含1个字符串元素的数组:

[["$6"], ["$12"], ["$25"], ["$25"]].join(',').split(',');

我会做好的。这是一个简短的函数,它使用一些较新的JavaScript数组方法来展平n维数组

function flatten(arr) {
  return arr.reduce(function (flat, toFlatten) {
    return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
  }, []);
}
用法:

flatten([[1, 2, 3], [4, 5]]); // [1, 2, 3, 4, 5]
flatten([[[1, [1.1]], 2, 3], [4, 5]]); // [1, 1.1, 2, 3, 4, 5]

有一个令人困惑的隐藏方法,它构造一个新数组而不改变原始数组:

var oldArray=[[1]、[2,3]、[4];
var newArray=Array.prototype.concat.apply([],oldArray);

console.log(newArray);//[1,2,3,4]
使用
reduce(回调[,initialValue])
方法
JavaScript 1.8

list.reduce((p,n) => p.concat(n),[]);

将完成这项工作。

对于更一般的情况,当您的数组中可能有一些非数组元素时,这是一个解决方案

function flattenArrayOfArrays(a, r){
    if(!r){ r = []}
    for(var i=0; i<a.length; i++){
        if(a[i].constructor == Array){
            r.concat(flattenArrayOfArrays(a[i], r));
        }else{
            r.push(a[i]);
        }
    }
    return r;
}
函数展平阵列远射线(a,r){
如果(!r){r=[]}

对于(var i=0;i来说,最好通过javascript reduce函数来实现

var arrays = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"], ["$0"], ["$15"],["$3"], ["$75"], ["$5"], ["$100"], ["$7"], ["$3"], ["$75"], ["$5"]];

arrays = arrays.reduce(function(a, b){
     return a.concat(b);
}, []);
或者,对于ES2015:

arrays = arrays.reduce((a, b) => a.concat(b), []);


这看起来像是递归的工作

  • 处理多级嵌套
  • 处理空数组和非数组参数
  • 没有突变
  • 不依赖现代浏览器功能
代码:

var flatten = function(toFlatten) {
  var isArray = Object.prototype.toString.call(toFlatten) === '[object Array]';

  if (isArray && toFlatten.length > 0) {
    var head = toFlatten[0];
    var tail = toFlatten.slice(1);

    return flatten(head).concat(flatten(tail));
  } else {
    return [].concat(toFlatten);
  }
};
flatten([1,[2,3],4,[[5,6],7]]);
// Result: [1, 2, 3, 4, 5, 6, 7] 
用法:

var flatten = function(toFlatten) {
  var isArray = Object.prototype.toString.call(toFlatten) === '[object Array]';

  if (isArray && toFlatten.length > 0) {
    var head = toFlatten[0];
    var tail = toFlatten.slice(1);

    return flatten(head).concat(flatten(tail));
  } else {
    return [].concat(toFlatten);
  }
};
flatten([1,[2,3],4,[[5,6],7]]);
// Result: [1, 2, 3, 4, 5, 6, 7] 

(基于@danhbear的评论,我只是将此作为一个单独的答案来写。)

我已经使用递归和闭包完成了

function flatten(arr) {

  var temp = [];

  function recursiveFlatten(arr) { 
    for(var i = 0; i < arr.length; i++) {
      if(Array.isArray(arr[i])) {
        recursiveFlatten(arr[i]);
      } else {
        temp.push(arr[i]);
      }
    }
  }
  recursiveFlatten(arr);
  return temp;
}
函数展平(arr){
var-temp=[];
函数递归展平(arr){
对于(变量i=0;i
更新:原来此解决方案不适用于大型阵列。如果您正在寻找更好、更快的解决方案,请查看。


只需扩展
arr
,并将其作为参数传递给
concat()
,它将所有数组合并为一个数组。它相当于
[].concat.apply([],arr)

您也可以尝试此方法进行深度展平:

function deepFlatten(arr) {
  return flatten(           // return shalowly flattened array
    arr.map(x=>             // with each x in array
      Array.isArray(x)      // is x an array?
        ? deepFlatten(x)    // if yes, return deeply flattened x
        : x                 // if no, return just x
    )
  )
}
请参阅上的演示

此答案中使用的ECMAScript 6元素的参考:


旁注:并非所有浏览器都支持像
find()
和arrow函数这样的方法,但这并不意味着你现在不能使用这些功能。只需使用-它就可以将ES6代码转换为ES5。

我前几天在闲逛并编写了。其中包含

function flatten(arrayOfArrays=[]){
  function* flatgen() {
    for( let item of arrayOfArrays ) {
      if ( Array.isArray( item )) {
        yield* flatten(item)
      } else {
        yield item
      }
    }
  }

  return [...flatgen()];
}

var flatArray = flatten([[1, [4]],[2],[3]]);
console.log(flatArray);
基本上,我正在创建一个在原始输入数组上循环的生成器,如果它找到一个数组,它将使用操作符与递归相结合来不断展平内部数组。如果项不是数组,它只是单个项。然后使用(也称为splat操作符)将生成器展平到一个新的数组实例中

我还没有测试过它的性能,但我认为这是一个使用生成器和yield*操作符的简单示例


不过,我还是在胡闹,所以我相信还有更多更高性能的方法可以做到这一点。

另一个功能型ECMAScript 6解决方案:

声明一个函数:

const flatten = arr => arr.reduce(
  (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
);
并使用它:

flatten( [1, [2,3], [4,[5,[6]]]] ) // -> [1,2,3,4,5,6]
const flatte=arr=>arr.reduce(
(a,b)=>a.concat(Array.isArray(b)?展平(b):b),[]
);

log(展平([1,2,3],[4,5],[6,7,8,9,10,11],[12,13])
这里的大多数答案对大型(例如200000个元素)阵列不起作用,即使有,也很慢。具有最佳性能,但对深度展平不起作用

下面是最快的解决方案,它也适用于具有多个嵌套级别的阵列

const flatten = function(arr, result = []) {
  for (let i = 0, length = arr.length; i < length; i++) {
    const value = arr[i];
    if (Array.isArray(value)) {
      flatten(value, result);
    } else {
      result.push(value);
    }
  }
  return result;
};
在我的机器上,这段代码大约需要14毫秒才能执行

嵌套数组 它与嵌套数组一起工作。此代码生成
[1,1,1,1,1,1]

具有不同嵌套级别的数组
像这样展平阵列没有任何问题。

请注意:
函数.prototype.apply
[].concat.apply([],阵列)
)或扩展操作符(
[].concat(…阵列)
)用于展平数组,两者都会导致大型数组的堆栈溢出,因为函数的每个参数都存储在堆栈上

下面是一个功能风格的堆栈安全实现,它将最重要的需求相互权衡:

  • 可重用性
  • 可读性
  • 简洁
  • 演出
//小的、可重用的辅助函数:
const foldl=f=>acc=>xs=>xs.reduce(uncurry(f),acc);//又称reduce
未成熟常数=f=>(a,b)=>f(a)(b);
const concat=xs=>y=>xs.concat(y);
//展平阵列的实际功能—一条不言自明的直线:
常数展平=xs=>foldl(concat)([])(xs);
//任意数组大小(直到堆爆炸:D)
常数xs=[[1,2,3],[4,5,6],[7,8,9];
console.log(展平(xs)
const flatten = function(arr, result = []) {
  for (let i = 0, length = arr.length; i < length; i++) {
    const value = arr[i];
    if (Array.isArray(value)) {
      flatten(value, result);
    } else {
      result.push(value);
    }
  }
  return result;
};
flatten(Array(200000).fill([1]));
flatten(Array(2).fill(Array(2).fill(Array(2).fill([1]))));
flatten([1, [1], [[1]]]);
let flatten = arr => [].concat.apply([], arr.map(item => Array.isArray(item) ? flatten(item) : item))
function flatten(arr) {
  return arr.reduce((acc, e) => acc.concat(e), []);
}
function flatten(arr) {
  return [].concat.apply([], arr);
}
test('already flatted', () => {
  expect(flatten([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
});

test('flats first level', () => {
  expect(flatten([1, [2, [3, [4]], 5]])).toEqual([1, 2, [3, [4]], 5]);
});
function flattenDeep(arr) {
  return arr.reduce((acc, e) => Array.isArray(e) ? acc.concat(flattenDeep(e)) : acc.concat(e), []);
}
test('already flatted', () => {
  expect(flattenDeep([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
});

test('flats', () => {
  expect(flattenDeep([1, [2, [3, [4]], 5]])).toEqual([1, 2, 3, 4, 5]);
});
const arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

// Flatten 2 levels deep
const arr3 = [2, 2, 5, [5, [5, [6]], 7]];
arr3.flat(2);
// [2, 2, 5, 5, 5, [6], 7];

// Flatten all levels
const arr4 = [2, 2, 5, [5, [5, [6]], 7]];
arr4.flat(Infinity);
// [2, 2, 5, 5, 5, 6, 7];
const common = arr.reduce((a, b) => [...a, ...b], [])