[JavaScript] 헤더 행이 있는 2차원 배열을 Map 배열로 변환

8599 단어 자바스크립트gas

목적



GAS(Google Apps Script)에서 Google 스프레드시트의 데이터를 sheet.getDataRange().getValues() 로 2차원 배열로 꺼낸 후 가공하여 setValues() 로 다시 쓰는 것은 자주 있다고 생각한다.

2차원 배열 그대로는 열의 추가나 삭제, 교환 등의 변경에 대해 약하기 때문에 지금까지는 Object로 변환하고 나서 처리하고 있었지만, Object에서는 키(프로퍼티)의 순서가 보증되지 않는다(= 스프레드시트에 다시 쓸 때 열의 순서가 바뀔 수 있습니다)라는 것을 알았으므로 순서가 보장되는지도로 변환하는 것.

그래서 첫 번째 줄이 헤더 인 2 차원 배열과 Map의 배열을 상호 변환하는 함수를 만들었습니다 (V8 엔진 한정).

할 수있는 것


/**
 * 2次元配列(第1行はヘッダ)をMapの配列に変換
 * @param {Array<Array>} table 第1行をヘッダとする2次元配列
 * @return {Array<Map>} Mapの配列
 */
function tableToMaps(table){
  const headers = table[0];
  return table.slice(1).map((e) => e.reduce((i,n,a) => i.set(headers[a], n), new Map()));
}

/**
 * Mapの配列を2次元配列(第1行はヘッダ)に変換
 * @param {Array<Map>} maps Mapsの配列
 * @return {Array<Array>} 第1行をヘッダとする2次元配列
 */
function mapsToTable(maps){
  const headers = [...maps[0].keys()];
  return [headers, ...maps.map((e) => (headers.map((h) => e.get(h))))]
}

에러 처리 등은 하지 않으므로 적당히 호출측에서 😁



2차원 배열 → Map 배열
const table = [
  ["col1", "col2", "col3", "col4"],
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  ["a", "b", "c", "d"]
];
const maps = tableToMaps(table);



Map 배열 → 2차원 배열
mapsToTable(maps);



보충



객체의 배열로 변환



덧붙여서 지금까지 사용하고 있던 Object의 배열과 2차원 배열의 상호 변환은 이하.
/**
 * 2次元配列(第1行はヘッダ)をオブジェクトの配列に変換
 * @param {Array<Array>} table 第1行をヘッダとする2次元配列
 * @return {Array<Object>} オブジェクトの配列
 */
function tableToObjects(table){
  const headers = table[0];
  return table.slice(1).map((e) => e.reduce((i,n,a) => {i[headers[a]] = n; return i;}, {}));
}

/**
 * オブジェクトの配列を2次元配列(第1行はヘッダ)に変換
 * @param {Array<Object>} objects オブジェクトの配列
 * @return {Array<Array>} 第1行をヘッダとする2次元配列
 */
function objectsToTable(objects){
  const headers = Object.keys(objects[0]);
  return [headers, ...objects.map((e) => (headers.map((h) => e[h])))];
}

덧붙여서 {i[headers[a]] = n; return i;}({...i, [headers[a]]: n}) 라고 쓰면 속도가 1/3 정도까지 떨어졌다.

좋은 웹페이지 즐겨찾기