source

어레이의 Marge/flatening

itover 2022. 11. 12. 08:49
반응형

어레이의 Marge/flatening

다음과 같은 JavaScript 배열이 있습니다.

[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]

개별 내부 어레이를 다음과 같은 어레이로 병합하려면 어떻게 해야 합니까?

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

하시면 됩니다.concat마지:

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

console.log(merged);

「 」의 apply의 of의 concat는 두 .

var merged2 = [].concat(["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]);

또한 어레이를 평평하게 하기 위해 사용할 수 있는 메서드(ES2019에서 도입)도 있습니다.단, Node.js 버전에서는 사용할 있지만 Internet Explorer에서는 사용할 수 없습니다.

const arrays = [
      ["$6"],
      ["$12"],
      ["$25"],
      ["$25"],
      ["$18"],
      ["$22"],
      ["$10"]
    ];
const merge3 = arrays.flat(1); //The depth level specifying how deep a nested array structure should be flattened. Defaults to 1.
console.log(merge3);
    

여기 새로운 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 ]

javascript reduced 기능으로 가장 잘 할 수 있습니다.

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), []);

js-discriptions(점수)

Mozilla 문서

이것을 정확하게 하기 위한 플랫이라는 새로운 네이티브 방법이 있습니다.

말 )flat표준에 되어 있습니다.또, ECMA 2019에도 게재되어 있습니다.core-js@3(babel's 라이브러리) 폴리필 라이브러리에 포함)

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];

이 답변의 대부분은 대규모(예: 200,000개의 요소) 어레이에서는 동작하지 않으며 동작하더라도 동작이 느립니다.polkovnikov.ph의 답변은 최고의 성능을 가지고 있지만, 깊은 평탄화에는 효과가 없습니다.

가장 빠른 솔루션은 다음과 같습니다.이 솔루션은 여러 레벨의 중첩이 있는 어레이에서도 작동합니다.

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]));

대용량 어레이를 완벽하게 처리합니다.제 기계에서는 이 코드를 실행하는 데 약 14밀리초가 걸립니다.

네스트된 어레이

flatten(Array(2).fill(Array(2).fill(Array(2).fill([1]))));

중첩된 배열과 함께 작동합니다., 「」가 생성됩니다.[1, 1, 1, 1, 1, 1, 1, 1].

네스트 레벨이 다른 어레이

flatten([1, [1], [[1]]]);

이와 같은 어레이를 평탄화하는 데 문제가 없습니다.

업데이트: 이 솔루션은 대규모 어레이에서는 작동하지 않는 것으로 나타났습니다.더 빠르고 더 나은 솔루션을 찾고 있다면 이 답을 확인하십시오.


function flatten(arr) {
  return [].concat(...arr)
}

순한장확확 is is를 전개하는 것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
    )
  )
}

JSBin 데모를 참조하십시오.

이 답변에서 사용된 ECMAScript 6 요소에 대한 참조:


노트: 이드 like : 음음음음음 like like find()모든 브라우저에서 화살표 및 화살표 기능이 지원되는 것은 아니지만, 이러한 기능을 사용할 수 없는 것은 아닙니다.Babel을 사용하면 ES6 코드가 ES5로 변환됩니다.

밑줄을 사용할 수 있습니다.

var x = [[1], [2], [3, 4]];

_.flatten(x); // => [1, 2, 3, 4]

일반적인 절차란 특정 동작을 이용해야 할 때마다 복잡성을 다시 작성할 필요가 없음을 의미합니다.

concatMap (오류)flatMap이 상황에서 필요한 것은 바로 이것입니다.

// 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))

선견지명

그래, 정확히 맞혔어. 딱 한 단계만 평평해지면 돼. 그게 정확히 작동 방식이야.

다음과 같은 데이터 세트를 상상해 보십시오.

// 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 ] ] ]

좋아, 이제 우리가 선수 명단을 인쇄하고 싶다고 가정해 보자.game

const gamePlayers = game =>
  flatten (game)

gamePlayers (game)
// => [ [ 'bob', 5 ], [ 'alice', 6 ], [ 'ricky', 4 ], [ 'julian', 2 ] ]

우리의 ★★★★★★★★★★★★★★★★★.flatten도 평평하게 결과가 .결국 이 가비지 결과가 됩니다.

const gamePlayers = game =>
  badGenericFlatten(game)

gamePlayers (game)
// => [ 'bob', 5, 'alice', 6, 'ricky', 4, 'julian', 2 ]

깊숙이 굴러, 자기

그렇다고 해서 네스트된 어레이를 평평하게 하고 싶지 않은 경우도 있습니다.기본 동작은 이것이 아닙니다.

deepFlatten

// 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 ]

, 즉를 한 도구, 즉 둥지를 짓누르는 입니다.flatten은 모든 데 사용됩니다.deepFlatten.

'하다'라고 될 것 같아요.obliterate ★★★★★★★★★★★★★★★★★」nuke이 들지 deepFlatten.


두 번 반복하지 마라!

하지만, 「」를 해 주세요..map이어서 할 것을 요구하다.reduce실제로 더 많은 을 하고 있다는 입니다.

할 수 있는 콜하고 .mapReduce하면 반복 할 수 합니다. 매핑 기능이 필요합니다.m :: a -> b 함수 「」r :: (b,a) ->b새로운 환원 함수를 반환합니다.이 조합기는 변환기의 핵심입니다.관심있다면, 그것에 대한 다른 답을 써놨습니다.

// 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 ]

단일 요소 배열의 배열을 평평하게 하려면 라이브러리를 가져올 필요가 없습니다. 단순 루프가 가장 단순하고 효율적인 솔루션입니다.

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

다운 투표자: 질문을 읽어주세요.다운 투표는 당신의 다른 문제에 맞지 않습니다.이 솔루션은 가장 빠르고 간단한 질문입니다.

기능적인 스타일의 또 다른 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 flatten = arr => arr.reduce(
         (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
       );


console.log( flatten([1, [2,3], [4,[5],[6,[7,8,9],10],11],[12],13]) )

최신 브라우저의 최신 릴리스에서 사용할 수 있는 네이티브 함수 Array.protype.flat()(ES6용 제안)도 고려하십시오.@(Mark Amery) 님이 댓글로 언급해 주셔서 감사합니다.

flat에는 배열 네스트의 파라미터는 ' 네스트'로, '배열 네스트'는 '배열 네스트'와 같습니다.1폴트입입니니다

[1, 2, [3, 4]].flat();                  // -> [1, 2, 3, 4]

[1, 2, [3, 4, [5, 6]]].flat();          // -> [1, 2, 3, 4, [5, 6]]

[1, 2, [3, 4, [5, 6]]].flat(2);         // -> [1, 2, 3, 4, 5, 6]

[1, 2, [3, 4, [5, 6]]].flat(Infinity);  // -> [1, 2, 3, 4, 5, 6]

let arr = [1, 2, [3, 4]];

console.log( arr.flat() );

arr =  [1, 2, [3, 4, [5, 6]]];

console.log( arr.flat() );
console.log( arr.flat(1) );
console.log( arr.flat(2) );
console.log( arr.flat(Infinity) );

새로운 방법을 시도해 볼 수도 있습니다.다음과 같은 방법으로 동작합니다.

let arr = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]].flat()

console.log(arr);

flat()는 최대까지 재귀적으로 연결됩니다.

3차원 이상의 어레이를 평탄화하려면 평탄화 방식을 여러 번 호출하면 됩니다.예: (3차원):

let arr = [1,2,[3,4,[5,6]]].flat().flat().flat();

console.log(arr);

조심해!

Array.flat() 방법은 비교적 새로운 것입니다.ie와 같은 오래된 브라우저에서는 이 방법이 구현되지 않았을 수 있습니다.모든 브라우저에서 코드를 사용하려면 JS를 이전 버전으로 변환해야 할 수 있습니다.MDN Web 문서에서 현재 브라우저와의 호환성을 확인합니다.

어레이에 어레이 이외의 요소가 포함되어 있는 경우, 보다 일반적인 경우의 솔루션.

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

'어디서'를 쓰면 요?reduce(callback[, initialValue])의 of의 JavaScript 1.8

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

그 일을 할 수 있을 거야.

const common = arr.reduce((a, b) => [...a, ...b], [])

중첩된 배열의 깊이에 대해 와 함께 사용할 수 있습니다.

var arr = [ [1,2,3,4], [1,2,[1,2,3]], [1,2,3,4,5,[1,2,3,4,[1,2,3,4]]], [[1,2,3,4], [1,2,[1,2,3]], [1,2,3,4,5,[1,2,3,4,[1,2,3,4]]]] ];

let flatten = arr.flat(Infinity)

console.log(flatten)

브라우저 호환성에 대해서는 여기를 체크

주의:언제Function.prototype.apply )[].concat.apply([], arrays) 연산자 「」 「」 「」[].concat(...arrays)에 둘 다 수 는 배열을 평탄화하기 위해 사용됩니다.함수의 모든 인수가 스택에 저장되기 때문에 둘 다 대규모 어레이의 스택 오버플로우를 일으킬 수 있습니다.

다음으로 가장 중요한 요건을 서로 비교한 기능적인 스타일의 스택 세이프 실장을 나타냅니다.

  • 재사용 가능성
  • 가독성
  • 간결성
  • 성능

// 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));

큐레이드 형태의 작은 화살표 함수, 함수 구성, 고차 함수에 익숙해지면 이 코드는 산문처럼 읽힌다.프로그래밍은 단순히 작은 구성 요소를 조합하는 것으로 이루어지며, 이러한 구성 요소는 어떠한 부작용도 포함하지 않기 때문에 항상 예상대로 작동합니다.

ES6 단일 라인 플랫

"lodash plat, 언더스코어 plat (shallow)" 참조

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]);
});

ES6 1라인 딥 플랫

lodash plate 보기깊이, 밑줄 플랫

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 input = [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]];
const output = [].concat(...input);
console.log(output); // --> ["$6", "$12", "$25", "$25", "$18", "$22", "$10"]

var array = [["$6"], ["$12","$16"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]
var a = array.flat(Infinity);
console.log(a);

공간 효율적인 발전기 기능을 권장합니다.

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

필요한 경우 다음과 같이 평탄한 값의 배열을 작성합니다.

let flattened = [...flatten([1,[2,[3,[4]]]])]; // [1, 2, 3, 4]

문자열 요소가 1개뿐인 배열의 경우:

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

그 일을 할 수 있을 거야특히 코드 예시와 일치하는 BT입니다.

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);

나는 재귀와 폐쇄를 이용하여 그것을 했다.

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;
}

ES6 방식:

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))

ES5 방법:flattenN-time nested 배열에 대한 ES3 폴백 기능:

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));

하면 lodash를 할 수 .flatten방법: https://lodash.com/docs/4.17.14#flatten

lodash의 장점은 어레이를 평평하게 만드는 방법도 있다는 것입니다.

i) 재귀적 : https://lodash.com/docs/4.17.14#flattenDeep

ii) 최대 n레벨의 네스트:https://lodash.com/docs/4.17.14#flattenDepth

예를들면

const _ = require("lodash");
const pancake =  _.flatten(array)

얼마 전 ES6 제너레이터를 가지고 장난을 치다가 이 요지를 썼습니다.그 안에...

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);

기본적으로는 원래 입력 어레이를 루프하는 제너레이터를 만듭니다.어레이가 발견되면 resurance와 함께 yield* 연산자를 사용하여 내부 어레이를 지속적으로 평탄화합니다.항목이 배열이 아닌 경우 단일 항목만 생성됩니다.그런 다음 ES6 스프레드 연산자(일명 스플래트 연산자)를 사용하여 제너레이터를 새로운 어레이 인스턴스로 평탄화합니다.

퍼포먼스를 테스트한 적은 없지만 발전기와 수율* 연산자를 사용하는 간단한 예라고 생각합니다.

하지만 다시 한 번 말하지만, 저는 그냥 장난치고 있었기 때문에 이것을 할 수 있는 더 좋은 방법이 있을 거라고 확신합니다.

lodash가 없는 최적의 솔루션

let flatten = arr => [].concat.apply([], arr.map(item => Array.isArray(item) ? flatten(item) : item))

배열 , 답변과 '열로 변환하다'로 합니다.JSON.stringify「 」를 사용하지 .toString() 않은 결과를.

★★★★★★★★★★★★★★★★★.JSON.stringify은 모든시작및 끝 괄호로 됩니다.JSON.parse 결과 끈이 '로 된다.라이프'로 돌아가게 됩니다.

  • 속도 비용 없이 무한 중첩 어레이를 처리할 수 있습니다.
  • 콤마를 포함하는 문자열인 배열 항목을 올바르게 처리할 수 있습니다.

var arr = ["abc",[[[6]]],["3,4"],"2"];

var s = "[" + JSON.stringify(arr).replace(/\[|]/g,'') +"]";
var flattened = JSON.parse(s);

console.log(flattened)

  • 문자열/숫자의 다차원 배열(개체가 아님)에만 해당

array.flat(Infinity)은 최적의 솔루션이라고 생각합니다.그러나 플랫 기능은 비교적 새로운 기능으로 이전 버전의 브라우저에서는 실행되지 않을 수 있습니다.이 문제를 해결하기 위해 재귀 함수를 사용할 수 있습니다.

const arr = ["A", ["B", [["B11", "B12", ["B131", "B132"]], "B2"]], "C", ["D", "E", "F", ["G", "H", "I"]]]
const flatArray = (arr) => {
    const res = []
    for (const item of arr) {
        if (Array.isArray(item)) {
            const subRes = flatArray(item)
            res.push(...subRes)
        } else {
            res.push(item)
        }
    }

    return res
}

console.log(flatArray(arr))

언급URL : https://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays

반응형