¿Combinar / aplanar una matriz de matrices en JavaScript?
Tengo una matriz JavaScript como:
[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]
¿Cómo podría fusionar los arreglos internos separados en uno como:
["$6", "$12", "$25", ...]
30 answers
Puede usar concat
para fusionar matrices:
var arrays = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];
var merged = [].concat.apply([], arrays);
Usando el método apply
de concat
simplemente tomará el segundo parámetro como una matriz, por lo que la última línea es idéntica a esta:
var merged2 = [].concat(["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-17 09:02:12
Aquí hay una función corta que utiliza algunos de los métodos de matriz JavaScript más nuevos para aplanar una matriz n-dimensional.
function flatten(arr) {
return arr.reduce(function (flat, toFlatten) {
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
}, []);
}
Uso:
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]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-02 17:40:35
Aquí hay una solución funcional simple y de rendimiento:
var result = [].concat.apply([], [[1],[2,3],[4]]);
console.log(result); // [ 1, 2, 3, 4 ]
No hay desorden imperativo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-20 21:17:24
Se puede hacer mejor mediante la función de reducción de javascript.
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);
}, []);
O, con ES2015:
arrays = arrays.reduce((a, b) => a.concat(b), []);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 07:39:15
La mayoría de las respuestas aquí no funcionan en matrices enormes (por ejemplo, 200 000 elementos), e incluso si lo hacen, son lentas. polkovnikov.ph ' s answer tiene el mejor rendimiento, pero no funciona para aplanamiento profundo.
Aquí está la solución más rápida, que también funciona en matrices con múltiples niveles de anidamiento :
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;
};
Ejemplos
Arreglos enormes
flatten(Array(200000).fill([1]));
Maneja matrices enormes muy bien. En mi máquina este código tarda unos 14 ms en ejecutar.
Matrices anidadas
flatten(Array(2).fill(Array(2).fill(Array(2).fill([1]))));
Funciona con matrices anidadas. Este código produce [1, 1, 1, 1, 1, 1, 1, 1]
.
Arrays con diferentes niveles de anidamiento
flatten([1, [1], [[1]]]);
No tiene ningún problema con el aplanamiento de matrices como esta.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-05 10:12:47
Actualización: resultó que esta solución no funciona con arreglos grandes. Si está buscando una solución mejor y más rápida, consulte esta respuesta.
function flatten(arr) {
return [].concat(...arr)
}
Es simplemente expande arr
y lo pasa como argumentos a concat()
, que fusiona todos los arrays en uno. Es equivalente a [].concat.apply([], arr)
.
También puedes probar esto para aplanar profundamente:
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
)
)
}
Ver demo en JSBin.
Referencias para los elementos de ECMAScript 6 utilizados en este respuesta:
Nota al margen: métodos como find()
y las funciones arrow no son compatibles con todos los navegadores, pero esto no significa que no pueda usar estas funciones en este momento. Simplemente use Babel - transforma el código ES6 en ES5.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:30
Puedes usar Subrayado :
var x = [[1], [2], [3, 4]];
_.flatten(x); // => [1, 2, 3, 4]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-02 18:58:38
Los procedimientos genéricos significan que no tenemos que reescribir la complejidad cada vez que necesitamos utilizar un comportamiento específico.
concatMap
(o flatMap
) es exactamente lo que necesitamos en esta situación.
// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
xs.concat (ys)
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
xs.map(f).reduce(concat, [])
// id :: a -> a
const id = x =>
x
// flatten :: [[a]] -> [a]
const flatten =
concatMap (id)
// your sample data
const data =
[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]
console.log (flatten (data))
Previsión
Y sí, lo adivinaste correctamente, solo aplana un nivel , que es exactamente cómo debería funcionar
Imagine un conjunto de datos como este
// Player :: (String, Number) -> Player
const Player = (name,number) =>
[ name, number ]
// team :: ( . Player) -> Team
const Team = (...players) =>
players
// Game :: (Team, Team) -> Game
const Game = (teamA, teamB) =>
[ teamA, teamB ]
// sample data
const teamA =
Team (Player ('bob', 5), Player ('alice', 6))
const teamB =
Team (Player ('ricky', 4), Player ('julian', 2))
const game =
Game (teamA, teamB)
console.log (game)
// [ [ [ 'bob', 5 ], [ 'alice', 6 ] ],
// [ [ 'ricky', 4 ], [ 'julian', 2 ] ] ]
Ok, ahora digamos que queremos imprimir una lista que muestra a todos los jugadores que participarán en game
{
const gamePlayers = game =>
flatten (game)
gamePlayers (game)
// => [ [ 'bob', 5 ], [ 'alice', 6 ], [ 'ricky', 4 ], [ 'julian', 2 ] ]
Si nuestro procedimiento flatten
arrays anidados aplanados también, terminaríamos con este resultado de basura {
const gamePlayers = game =>
badGenericFlatten(game)
gamePlayers (game)
// => [ 'bob', 5, 'alice', 6, 'ricky', 4, 'julian', 2 ]
Rollin ' deep, baby]}
Eso no quiere decir que a veces no quiera aplanar matrices anidadas, también – solo que ese no debería ser el comportamiento predeterminado.
Podemos hacer un procedimiento deepFlatten
con facilidad {
// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
xs.concat (ys)
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
xs.map(f).reduce(concat, [])
// id :: a -> a
const id = x =>
x
// flatten :: [[a]] -> [a]
const flatten =
concatMap (id)
// deepFlatten :: [[a]] -> [a]
const deepFlatten =
concatMap (x =>
Array.isArray (x) ? deepFlatten (x) : x)
// your sample data
const data =
[0, [1, [2, [3, [4, 5], 6]]], [7, [8]], 9]
console.log (flatten (data))
// [ 0, 1, [ 2, [ 3, [ 4, 5 ], 6 ] ], 7, [ 8 ], 9 ]
console.log (deepFlatten (data))
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Ahí. Ahora tienes una herramienta para cada trabajo-uno para aplastar un nivel de anidamiento, flatten
, y uno para borrar todo el anidamiento deepFlatten
.
Tal vez puedas llamarlo obliterate
o nuke
si no te gusta el nombre deepFlatten
.
¡No iteres dos veces !
Por supuesto, las implementaciones anteriores son inteligentes y concisas, pero usar un .map
seguido de una llamada a .reduce
significa que en realidad estamos haciendo más iteraciones de las necesarias
El uso de un combinador de confianza que estoy llamando mapReduce
ayuda a mantener el iteraciones a un minio; toma una función de mapeo m :: a -> b
, una función de reducción r :: (b,a) ->b
y devuelve una nueva función de reducción-este combinador está en el corazón de transductores ; si estás interesado, He escrito otras respuestas sobre ellos
// mapReduce = (a -> b, (b,a) -> b, (b,a) -> b)
const mapReduce = (m,r) =>
(acc,x) => r (acc, m (x))
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = f => xs =>
xs.reduce (mapReduce (f, concat), [])
// concat :: ([a],[a]) -> [a]
const concat = (xs,ys) =>
xs.concat (ys)
// id :: a -> a
const id = x =>
x
// flatten :: [[a]] -> [a]
const flatten =
concatMap (id)
// deepFlatten :: [[a]] -> [a]
const deepFlatten =
concatMap (x =>
Array.isArray (x) ? deepFlatten (x) : x)
// your sample data
const data =
[ [ [ 1, 2 ],
[ 3, 4 ] ],
[ [ 5, 6 ],
[ 7, 8 ] ] ]
console.log (flatten (data))
// [ [ 1. 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ] ]
console.log (deepFlatten (data))
// [ 1, 2, 3, 4, 5, 6, 7, 8 ]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-28 07:21:38
Una solución para el caso más general, cuando puede tener algunos elementos no-array en su matriz.
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-28 01:28:19
Para aplanar una matriz de matrices de un solo elemento, no necesita importar una biblioteca, un bucle simple es la solución más simple y más eficiente :
for (var i = 0; i < a.length; i++) {
a[i] = a[i][0];
}
Para los downvoters: por favor, lea la pregunta, no vote en contra porque no se adapta a su problema muy diferente. Esta solución es a la vez la más rápida y simple para la pregunta planteada.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-08 07:20:23
Hay un nuevo método nativo de ECMA 2018 llamado flat para hacer esto exactamente.
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]]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-30 12:23:32
Otra solución ECMAScript 6 en estilo funcional:
Declarar función:
const flatten = arr => arr.reduce(
(a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
);
Y úsalo:
flatten( [1, [2,3], [4,[5,[6]]]] ) // -> [1,2,3,4,5,6]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-01 10:49:11
¿Qué hay de usar reduce(callback[, initialValue])
método de JavaScript 1.8
list.reduce( function( p,n){
return p.concat( n );
},[]);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-30 11:50:33
Tenga en cuenta: Cuando Function.prototype.apply
([].concat.apply([], arrays)
) o el operador spread ([].concat(...arrays)
) se usa para aplanar una matriz, ambos pueden causar desbordamientos de pila para matrices grandes, porque cada argumento de una función se almacena en la pila.
Aquí hay una implementación segura para apilar en estilo funcional que compara los requisitos más importantes con uno otro:
- reutilización
- legibilidad
- concisión
- rendimiento
// small, reusable auxiliary functions:
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc); // aka reduce
const uncurry = f => (a, b) => f(a) (b);
const concat = xs => y => xs.concat(y);
// the actual function to flatten an array - a self-explanatory one-line:
const flatten = xs => foldl(concat) ([]) (xs);
// arbitrary array sizes (until the heap blows up :D)
const xs = [[1,2,3],[4,5,6],[7,8,9]];
console.log(flatten(xs));
// Deriving a recursive solution for deeply nested arrays is trivially now
// yet more small, reusable auxiliary functions:
const map = f => xs => xs.map(apply(f));
const apply = f => a => f(a);
const isArray = Array.isArray;
// the derived recursive function:
const flattenr = xs => flatten(map(x => isArray(x) ? flattenr(x) : x) (xs));
const ys = [1,[2,[3,[4,[5],6,],7],8],9];
console.log(flattenr(ys));
Tan pronto como te acostumbras a las pequeñas funciones de flecha en forma de curry, composición de funciones y funciones de orden superior, este código se lee como prosa. La programación consiste simplemente en armar pequeños bloques de construcción que siempre funcionan como se espera, porque no contienen ningún efecto secundario.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-23 16:34:08
const common = arr.reduce((a, b) => [...a, ...b], [])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-27 08:53:16
var arrays = [["a"], ["b", "c"]];
Array.prototype.concat.apply([], arrays);
// gives ["a", "b", "c"]
(Solo estoy escribiendo esto como una respuesta separada, basada en el comentario de @danhbear.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-16 07:32:53
ES6 Una línea Aplanada
Ver lodash aplanar, subrayar aplanar (poco profundo true
)
function flatten(arr) {
return arr.reduce((acc, e) => acc.concat(e), []);
}
function flatten(arr) {
return [].concat.apply([], arr);
}
Probado con
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]);
});
ES6 Una línea Profunda Aplanar
Véase lodash flattenDeep, subrayar aplanar
function flattenDeep(arr) {
return arr.reduce((acc, e) => Array.isArray(e) ? acc.concat(flattenDeep(e)) : acc.concat(e), []);
}
Probado con
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]);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-22 22:00:19
Si solo tiene arrays con 1 elemento string:
[["$6"], ["$12"], ["$25"], ["$25"]].join(',').split(',');
Hará el trabajo. Bt que coincide específicamente con su ejemplo de código.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-02 19:18:08
Lo he hecho usando recursión y cierres
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-29 12:10:50
Preferiría transformar toda la matriz, tal cual, en una cadena, pero a diferencia de otras respuestas, lo haría usando JSON.stringify
y no usando el método toString()
, que produce un resultado no deseado.
Con esa salida JSON.stringify
, todo lo que queda es eliminar todos los corchetes, envolver el resultado con corchetes de inicio y final una vez más, y servir el resultado con JSON.parse
que devuelve la cadena a "vida".
- Puede manejar arrays anidados infinitos sin ningún costo de velocidad.
- Puede manejar correctamente Elementos de matriz que son cadenas que contienen comas.
var arr = ["abc",[[[6]]],["3,4"],"2"];
var s = "[" + JSON.stringify(arr).replace(/\[|]/g,'') +"]";
var flattened = JSON.parse(s);
console.log(flattened)
var arr = ["abc",[[[6]]],["3,4"],"2"];
var s = "[" + JSON.stringify(arr).replace(/\[|]/g,'') +"]";
var flattened = JSON.parse(s);
console.log(flattened)
- Solo para Matriz multidimensional de Cadenas / Números (no Objetos)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-02 09:02:14
ES6 manera:
const flatten = arr => arr.reduce((acc, next) => acc.concat(Array.isArray(next) ? flatten(next) : next), [])
const a = [1, [2, [3, [4, [5]]]]]
console.log(flatten(a))
Forma ES5 para la función flatten
con respaldo ES3 para matrices anidadas N veces:
var flatten = (function() {
if (!!Array.prototype.reduce && !!Array.isArray) {
return function(array) {
return array.reduce(function(prev, next) {
return prev.concat(Array.isArray(next) ? flatten(next) : next);
}, []);
};
} else {
return function(array) {
var arr = [];
var i = 0;
var len = array.length;
var target;
for (; i < len; i++) {
target = array[i];
arr = arr.concat(
(Object.prototype.toString.call(target) === '[object Array]') ? flatten(target) : target
);
}
return arr;
};
}
}());
var a = [1, [2, [3, [4, [5]]]]];
console.log(flatten(a));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-20 10:50:18
Parece que esto parece un trabajo para RECURSIÓN!
- Maneja múltiples niveles de anidamiento
- Maneja arrays vacíos y parámetros no array
- No tiene mutación
- No se basa en las características del navegador moderno
Código:
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);
}
};
Uso:
flatten([1,[2,3],4,[[5,6],7]]);
// Result: [1, 2, 3, 4, 5, 6, 7]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-01 03:35:37
La mejor solución sin lodash
let flatten = arr => [].concat.apply([], arr.map(item => Array.isArray(item) ? flatten(item) : item))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-07 10:20:52
Un enfoque Haskellesque
function flatArray([x,...xs]){
return x ? [...Array.isArray(x) ? flatArray(x) : [x], ...flatArray(xs)] : [];
}
var na = [[1,2],[3,[4,5]],[6,7,[[[8],9]]],10];
fa = flatArray(na);
console.log(fa);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-01 15:49:26
Eso no es difícil, simplemente iterar sobre los arrays y fusionarlos:
var result = [], input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"]];
for (var i = 0; i < input.length; ++i) {
result = result.concat(input[i]);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-02 18:56:43
La lógica aquí es convertir la matriz de entrada en cadena y eliminar todos los corchetes([]) y analizar la salida a la matriz. Estoy usando la función de plantilla ES6 para esto.
var x=[1, 2, [3, 4, [5, 6,[7], 9],12, [12, 14]]];
var y=JSON.parse(`[${JSON.stringify(x).replace(/\[|]/g,'')}]`);
console.log(y)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-24 12:42:31
Yo estaba jugando con Generadores ES6 el otro día y escribió esta esencia . Que contiene...
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);
Básicamente estoy creando un generador que gira sobre la matriz de entrada original, si encuentra una matriz utiliza el operador yield* en combinación con la recursión para aplanar continuamente las matrices internas. Si el elemento no es una matriz, simplemente produce el elemento único. A continuación, utilizando el ES6 operador de propagación (también conocido como operador splat) aplanar el generador en una nueva instancia de matriz.
No he probado el rendimiento de esto, pero me imagino que es un buen ejemplo simple de usar generadores y el operador yield*.
Pero de nuevo, solo estaba haciendo el tonto, así que estoy seguro de que hay formas más eficientes de hacer esto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-28 22:42:39
Propongo dos soluciones cortas sin recursión. No son óptimos desde el punto de vista de la complejidad computacional, pero funcionan bien en casos promedio:
let a = [1, [2, 3], [[4], 5, 6], 7, 8, [9, [[10]]]];
// Solution #1
while (a.find(x => Array.isArray(x)))
a = a.reduce((x, y) => x.concat(y), []);
// Solution #2
let i = a.findIndex(x => Array.isArray(x));
while (i > -1)
{
a.splice(i, 1, ...a[i]);
i = a.findIndex(x => Array.isArray(x));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-30 16:11:53
const flatten = array => array.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
Por solicitud, desglosar la línea es básicamente tener esto.
function flatten(array) {
// reduce traverses the array and we return the result
return array.reduce(function(acc, b) {
// if is an array we use recursion to perform the same operations over the array we found
// else we just concat the element to the accumulator
return acc.concat( Array.isArray(b) ? flatten(b) : b);
}, []); // we initialize the accumulator on an empty array to collect all the elements
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-16 02:07:12
Recomiendo una función de generador de espacio eficiente :
function* flatten(arr) {
if (!Array.isArray(arr)) yield arr;
else for (let el of arr) yield* flatten(el);
}
// Example:
console.log(...flatten([1,[2,[3,[4]]]])); // 1 2 3 4
Si lo desea, cree una matriz de valores aplanados de la siguiente manera:
let flattened = [...flatten([1,[2,[3,[4]]]])]; // [1, 2, 3, 4]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-22 02:32:23