Programming Language/🟨 Javascript

nested Array 다루기 : flat 평탄화, Table 형태의 array

DarrenKwonDev 2020. 12. 30. 22:36

flat

 

flat은 n중 array를 평탄화 하는 메서드입니다.

array.prototype.flat(depth) // depth default : 1

 

예를 들어 다음과 같은 2중 array가 있으면 depth 1을 주어 평탄화 작업을 할 수 있습니다.

[[], [], [{name: "xah"}], [{name: "darren"}, {name:"kyung"}]].flat(1)

// output : [{name: "xah"},{name: "darren"}, {name:"kyung"}]

 

만약 모조리 평탄화시키고 싶으시다면 depth에 Infinity를 주시면 됩니다.

const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

 

테이블 array 다루기

 

아래와 같은 2중 array가 있다고 보자. (주식, 코인 거래소 작업을 하면 많이 보게 될 형태의 array이다)

딱봐도 이건 table 형태의 array이다.

csv를 행마다 array로 담아도 이렇게 보일 것이다.

const arr1 = [
  ["name", "id", "age", "weight", "Cool"],
  ["Susan", "3", "20", "120", true],
  ["John", "1", "21", "150", true],
  ["Bob", "2", "23", "90", false],
  ["Ben", "4", "20", "100", true],
];

console.table(arr1);

 

 

  • 테이블의 행/열 세팅하기

첫번째 원소가 행, 나머지 원소가 열에 해당하므로 이를 이용하여 테이블 형태로 만들어보자

function parseArray(arr) {
  // column과 record를 분리
  const [columns, ...records] = arr;

  // reduce를 사용하여 각 column을 key 삼아 돌려서 person에 object 형태로 저장
  return records.reduce((acc, cur) => {
    const person = {};

    for (const [index, column] of columns.entries()) {
      person[column] = cur[index]; // { name: 'Susan', id: '3', age: '20', weight: '120', Cool: true }
    }

    return [...acc, person];
  }, []);
}

console.table(parseArray(arr1));

 

  • 테이블 outer join하기

아래와 같은 arr들이 존재할 때, 이들을 merge 하려고 한다.

const arr1 = [
  ["name", "id", "age", "weight", "Cool"],
  ["Susan", "3", "20", "120", true],
  ["John", "1", "21", "150", true],
  ["Bob", "2", "23", "90", false],
  ["Ben", "4", "20", "100", true],
];

const arr2 = [
  ["name", "id", "height"],
  ["Bob", "2", "50"],
  ["John", "1", "45"],
  ["Ben", "4", "43"],
  ["Susan", "3", "48"],
];

const arr3 = [
  ["name", "id", "parent"],
  ["Bob", "2", "yes"],
  ["John", "1", "yes"],
];

 

우선 각 테이블들을 행/열 세팅해준 후 하나의 array로 몰아주자

// 우선 모든 record를 하나의 array에 몰아주자
const allData = [...parseArray(arr1), ...parseArray(arr2), ...parseArray(arr3)];

console.log(allData); // [{name: "darren", id: '1' ...}, {...}, ...]

 

논리는 간단합니다. acc array에 이미 있으면 덮어쓰고, 없으면 새로 만들어내는 겁니다.

const merged = allData.reduce((acc, currPerson) => {
  console.log(`starting ${currPerson.name}`);
  // if they are already in the acc, then merge their objects, otherise add them
  const existingPersonIndex = acc.findIndex((person) => person.id === currPerson.id);

  // 이미 있다면
  if (existingPersonIndex >= 0) {
    acc[existingPersonIndex] = {
      ...acc[existingPersonIndex],
      ...currPerson, // 새로운 값들을 추가해주자
    };
    return acc;
  }

  // 없으니까 더해줘야 함
  return [...acc, currPerson];
}, []);

console.table(merged);