2017-06-29 13 views
1

私は現在、2つの列を持つリストを持っています。最初の列は生徒の名前で、2番目の列は生徒の所在地の数です。重複するセルをGoogleアプリケーションスクリプトと一緒にマージするにはどうすればよいですか?

複数のスプレッドシートからこのリストをインポートしたので、生徒の名前に重複が多数ありました。私は重複を取り除くことができますが、私は彼らが持っている合計点を集計したいと思います。例:これは私がこれまで持っているものである

エイミー22 ボブ9 キャロル15

エイミー10 ボブ9 キャロル15 エイミー12

はに変わるだろう。

var target = SpreadsheetApp.getActiveSpreadsheet(); 
 
    var sheet = target.getSheetByName("Sheet2"); 
 
    var data = sheet.getRange("A2:B1000").getValues(); 
 
    var newData = new Array(); 
 
    var k = 0 
 
    var finallist = [] 
 
    for(i in data){ 
 
    k++; 
 
    var row = data[i]; 
 
    var duplicate = false; 
 
    for(j in newData){ 
 
     if(row[0] == newData[j][0]){ 
 
     duplicate = true; 
 
     var storedHour = sheet.getRange("B"+k).getValue(); 
 
     var position = finallist.indexOf(row[0]); 
 
     var originalCell = sheet.getRange("B"+(position+1)); 
 
     var originalHour = originalCell.getValue(); 
 
     originalCell.setValue(originalHour + storedHour); 
 
     sheet.getRange(k,2).setValue("") 
 
     sheet.getRange(k,1).setValue("") 
 
     } 
 
    } 
 
    if(!duplicate){ 
 
     newData.push(row); 
 
     finallist.push(row[0]) 
 
    } 
 
    } 
 
}

問題は、私たちは非常に大きなデータサンプルを持っており、Googleの5分間の最大実行時間を超えてしまう恐れがあることです。私の目標を達成するためのさらに効率的な方法がありますか?

+0

あなたは期待どおりに動作していないのですか?あなたは何を持っているのですか? – Tom

+1

申し訳ありません説明に実際の問題を入れているのを忘れてしまいました。どのように不注意。私はコードをより効率的にする方法を考えていました。なぜなら、私はGoogleの5分間の最大実行時間の下で実行したいからです。これを説明に追加します。 –

+0

母、簡単に、心配することはありません。私はGoogle Scriptについてはあまりよく分かりませんが、MapReduceのような気持ちになるか、タスクを別の仕事に分割するとうまくいくかもしれません。 – Tom

答えて

1

スプレッドシートAPIメソッド(getRangeなど)が他のJavaScriptコードよりも時間がかかり、時間がかかるため、コードが低速です。

function calcNumbers() 
{ 
    var target = SpreadsheetApp.getActiveSpreadsheet(); 
    var sheet = target.getSheetByName("Sheet2"); 
    var lastRow = sheet.getLastRow(); 
    var dataRange = sheet.getRange(2, 1, lastRow-1, 2); 
    var data = dataRange.getValues(); 
    var pointsByName = {}; 

    for (var i = 0; i < data.length; i++) 
    { 
    var row = data[i]; 
    var curName = row[0]; 
    var curNumber = row[1]; 

    // empty name 
    if (!curName.trim()) 
    { 
     continue; 
    } 

    // if name found first time, save it to object 
    if (!pointsByName[curName]) 
    { 
     pointsByName[curName] = Number(curNumber); 
    } 
    // if duplicate, sum numbers 
    else 
    { 
     pointsByName[curName] += curNumber; 
    } 
    } 

    // prepare data for output 
    var outputData = Object.keys(pointsByName).map(function(name){ 
    return [name, pointsByName[name]]; 
    }); 

    // clear old data 
    dataRange.clearContent(); 

    // write calculated data 
    var newDataRange = sheet.getRange(2, 1, outputData.length, 2); 
    newDataRange.setValues(outputData); 
} 
+0

タリーボードに似たもの。私はそれが好きです。 – ScampMichael

0

比較する前にソートすると、次の項目だけではなく、各反復のためのすべての項目を見ていることができます:ここで

は、このようなスプレッドシートのAPI呼び出しの数が減少して機能を最適化されています。スピルオーバーの利点は、最終結果がアルファベットであることです。実行時間の短縮は重要です。

function sumDups() { 
    var target = SpreadsheetApp.getActiveSpreadsheet(); 
    var sheet = target.getSheetByName("Sheet2"); 
    var data = sheet.getRange("A2:B" + sheet.getLastRow()).getValues().sort(); 
    var finallist = []; 
    for(var i = 0; i<= data.length - 1; i++){ 
    var hours = data[i][1]; 
    while((i < data.length - 1) && (data[i][0] == data[i+1][0])) { 
     hours += data[i+1][1]; 
     i++; 
     }; 
    finallist.push([data[i][0], hours]); 
    }; 
    Logger.log(finallist); 
} 

編集:最初の列に名前がある単純なデータ構造がこれを可能にします。何かもっと複雑な理解と@ Kosの答えに示されている方法を適用するのが望ましい

関連する問題