You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apps Script技术求助:按Country唯一值合并多行数据为指定格式多维数组

问题描述

我有一个Google Sheet,每次更新时行列数都会动态变化,数据如下:

countryproducttypeuser
JPp1t1u1
JPp1t2u2
JPp1t3u2
JPp2t2u3
HKp3t2u1
HKp1t3u1
KRp1t2u1

我需要将数据存入一个数组,以country列的唯一值为分组依据,将其余列的唯一值合并(用/连接),数组的维度由country列的唯一值数量决定,上述示例应为二维数组(注:原描述的“三维数组”应为笔误,实际是二维数组,每个子数组对应一个国家的聚合结果)。

期望输出数组格式如下:
[["JP","p1/p2","t1/t2/t3","u1/u2/u3"],["HK","p1/p3","t2/t3","u1"],["KR","p1","t2","u1"]]

目前我只能得到如下格式的数组,无法将同一列的值用/连接:
[["JP","p1","p2","t1","t2","t3","u1","u2","u3"],["HK","p1","p3","t2","t3","u1"],["KR","p1","t2","u1"]]

以下是我的代码,请问问题出在哪里?

function testtogetcombine() {
  var spreadsheet =  SpreadsheetApp.getActiveSpreadsheet();
 var sheet1 = spreadsheet.getSheetByName("test");
  var lastRow = sheet1.getLastRow();
  var lastColumn = sheet1.getLastColumn();
  var values = sheet1.getRange(1, 1, lastRow, lastColumn).getValues();
  
  var newSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('outcome');
  var outLastRow = newSheet.getLastRow();
  var counter=1;
  
  var orgtitle=["country","product","type","user"]
 
  var col_geo=[];
  var geo=[];
 
  for (var c=0; c<=orgtitle.length;c++)  {
    for (var j=0;j<=lastColumn-1;j++) {
      if(values[0][j]==orgtitle[c] ){ 
              col_geo.push(j)
        }
    }
  }
  for (var i=1;i<lastRow-1;i++) {
         var duplicate = false;
           for (n in geo){
             if(values[i][col_geo[0]]==geo[n]){
                duplicate = true;
             }
            }
              if(!duplicate) {

               geo.push(values[i][col_geo[0]])

              }

  }

  var result=new Array(geo.length);
  for (var j=0;j<result.length;j++){
        result[j]=[];
        result[j].push(geo[j])

  }
var temp=[];
 for (var j=0;j<result.length;j++){
         
for (var c=0; c<col_geo.length;c++) {
               // temp[c]=[]; 
            
        for (var i=0;i<lastRow;i++){
        
              if (values[i][col_geo[0]] == result[j][0]) { 
                  //  temp[c].push(values[i][col_geo[c]]);
                 var duplicate = false;
           for (n in result[j]){
             if(values[i][col_geo[c]]==result[j][n]){
                duplicate = true;
             }
            }
              if(!duplicate) {
            
               
              result[j].push(values[i][col_geo[c]]);

              }
       
              }
              
          //  if (values[i][col_geo[0]] == "JP"){
             
          //    var duplicate = false;
          //  for (n in temp){
          //    if(values[i][col_geo[c]]==temp[n]){
          //       duplicate = true;
          //    }
          //   }
          //     if(!duplicate) {
                
              
          //      temp.push(values[i][col_geo[c]]);
          //      Logger.log(temp)
          //      temp=[];

          //     }        
       

           
                
           }

        }

       
            
 }  
    Logger.log(result);
    }

问题分析与解决方案

核心问题

你的代码当前是把每个唯一值逐个追加到result[j]数组中,没有针对每一列单独收集唯一值后再用/拼接:

  1. 没有为每个国家的每一列(product、type、user)单独维护唯一值集合,而是直接把所有列的唯一值堆到同一个数组里。
  2. 缺少将同一列的唯一值用/连接的步骤,导致最终数组是扁平化的多个值,而非拼接后的字符串。
  3. 原循环i<lastRow-1会跳过最后一行数据,导致部分信息丢失。

修正后的代码

function testtogetcombine() {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet1 = spreadsheet.getSheetByName("test");
  const lastRow = sheet1.getLastRow();
  const values = sheet1.getRange(1, 1, lastRow, sheet1.getLastColumn()).getValues();
  
  // 获取表头对应的列索引
  const orgtitle = ["country", "product", "type", "user"];
  const colIndices = orgtitle.map(title => values[0].indexOf(title));
  
  // 按country分组,用Set自动去重存储各列值
  const countryGroups = {};
  for (let i = 1; i < lastRow; i++) {
    const row = values[i];
    const country = row[colIndices[0]];
    
    if (!countryGroups[country]) {
      // 初始化分组:[国家名, product集合, type集合, user集合]
      countryGroups[country] = [country, new Set(), new Set(), new Set()];
    }
    
    // 将对应列的值加入Set(自动去重)
    countryGroups[country][1].add(row[colIndices[1]]);
    countryGroups[country][2].add(row[colIndices[2]]);
    countryGroups[country][3].add(row[colIndices[3]]);
  }
  
  // 将Set转为/连接的字符串,生成最终数组
  const result = Object.values(countryGroups).map(group => {
    return [
      group[0],
      [...group[1]].join('/'),
      [...group[2]].join('/'),
      [...group[3]].join('/')
    ];
  });
  
  Logger.log(result);
}

关键改进点

  1. 对象分组+Set去重:用countryGroups对象按国家分组,每个分组内用Set存储对应列的唯一值,Set会自动处理重复值,比手动判断更高效。
  2. 列维度独立处理:为每个国家的product、type、user列分别维护独立的Set,确保同一列的唯一值被集中收集。
  3. 字符串拼接:最后将每个Set转为数组,用join('/')拼接成目标格式的字符串,再组合成最终数组。
  4. 修复数据遗漏:循环从i=1到i<lastRow,确保所有数据行都被处理。

内容的提问来源于stack exchange,提问作者keavy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:05:19