У меня есть столбец с данными в таблицах Google, например:
col_name
A
A
A
B
B
C
Я хочу сохранить эти данные в словаре, где значение столбца является ключом, а количество вхождений — значением:
dict = {A:3, B:2, C:1}
Я попытался перебрать список значений:
col_values = mySheet.getRange(2, col, last_row-1, 1).getValues();
С функцией:
function count_occurances_in_col(col_values){
let occurances_dict = new Map();
for(var i=0;i<=col_values.length;i++){
if (occurances_dict.has(col_values[i][0])){
let value = occurances_dict.get(col_values[i][0]);
occurances_dict.set(col_values[i][0], value+1);
} else {
occurances_dict.set(col_values[i][0], 1);
}
}
return occurances_dict;
};
Но вместо словаря функция возвращает undefine (возможно), потому что ключи задаются динамически (если я правильно понял по форумам — я плохо знаю JS, только python).
Могу ли я получить такой словарь с какой-либо функцией или каким-либо другим способом?
Обратите внимание, что метод getValues() возвращает значения col_values в форме:
[[A], [A], [A], [B], [B], [C]]
Это должно сработать
const col = 1;
const last_row = mySheet.getLastRow();
col_values = mySheet.getRange(2, col, last_row - 1, 1).getValues();
function count_occurances_in_col(col_values) {
let occurances_dict = {};
for (var i = 0; i <= col_values.length -1 ; i++) {
if (occurances_dict[col_values[i][0]] != undefined) {
occurances_dict[col_values[i][0]] += 1;
} else {
occurances_dict[col_values[i][0]] = 1;
}
}
return occurances_dict;
};
Самый простой способ получить словарь — использовать простой ванильный объект Object, например:
function countOccurances(keys = [], dict = {}) {
keys.forEach(v => dict[v] = 1 + (Number(dict[v]) || 0));
return dict;
}
Приведенную выше функцию можно вызвать с помощью всего лишь массива keys
, и она вернет новый Object
, который выглядит как { A: 3, B: 2, C: 1 }
.
Функцию также можно вызвать с использованием существующего словаря, и в этом случае функция изменит этот словарь, увеличивая счетчики и добавляя ключи по мере необходимости.
Чтобы проверить функцию, попробуйте что-то вроде этого:
function test() {
const ss = SpreadsheetApp.getActive();
const keys = ss.getRange('Sheet1!A2:A').getValues().flat().filter(String);
const result = countOccurances(keys);
console.info(result);
return result;
}
Функция test()
зарегистрирует и вернет результат в формате { A: 3, B: 2, C: 1 }
.
Вот пример использования Установите, чтобы получить уникальные значения col_values, а затем подсчитать количество вхождений.
Код.gs
function test() {
try {
let spread = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spread.getSheetByName("Test");
let col = 1;
let last_row = sheet.getLastRow();
let col_values = sheet.getRange(2,col,last_row-1,1).getValues().flat();
let keys = [...new Set(col_values)];
let dict = {};
keys.forEach( key => dict[key] = 0 );
col_values.forEach( key => dict[key[0]]++ );
console.info(dict);
}
catch(err) {
console.info("Error in test: "+err)
}
}
Журнал выполнения
7:02:47 AM Notice Execution started
7:02:48 AM Info { A: 3, B: 2, C: 1 }
7:02:48 AM Notice Execution completed
Попробуйте это:
function myfunk() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const obj = sh.getRange(2,1,sh.getLastRow() - 1).getValues().flat().reduce((a,v,i) => {
if (!a.hasOwnProperty(v)) {
a[v]=1;
} else {
a[v] += 1;
}
return a;
},{});
Logger.log(JSON.stringify(obj))
}
Execution log
11:24:06 AM Notice Execution started
11:24:03 AM Info {"A":3,"B":2,"C":1}
11:24:08 AM Notice Execution completed
Примечание. Все ответы других членов сообщества работают. Это сделано для предоставления дополнительной информации о том, где можно запустить код, поскольку было указано
I don't know JS well, only python
.
Если сценарий предназначен для использования в качестве пользовательских функций в Google Таблицах, вы можете изменить код следующим образом:
function count_occurances_in_col(col_values) {
let occurances_dict = {};
for (var i = 0; i < col_values.length; i++) {
let value = col_values[i];
if (occurances_dict[value]) {
occurances_dict[value] += 1;
} else {
occurances_dict[value] = 1;
}
}
console.info(occurances_dict);
return JSON.stringify(occurances_dict);
}
Здесь используется JSON.stringify(), чтобы объект отображался в электронной таблице, и его можно использовать следующим образом:
=count_occurances_in_col(range)
ВЫХОД
На вкладке
Executions
скрипта Google Apps также будет отображаться что-то подобное, если вы решите сохранитьconsole.info(occurances_dict);
.
Если сценарий предназначен для использования в Google Apps Script, вы можете изменить код следующим образом:
function count_occurances_in_col() {
var ss = SpreadsheetApp.getActiveSheet();
var col_values = ss.getRange(2, 1, ss.getLastRow() - 1).getValues();
let occurances_dict = {};
for (var i = 0; i < col_values.length; i++) {
let value = col_values[i];
if (occurances_dict[value]) {
occurances_dict[value] += 1;
} else {
occurances_dict[value] = 1;
}
}
console.info(occurances_dict);
}
ВЫХОД
Это еще один способ написания сценария:
function count_occurances_in_col() {
var ss = SpreadsheetApp.getActiveSheet();
var col_values = ss.getRange(2, 1, ss.getLastRow() - 1).getValues();
let occurances_dict = {};
col_values.forEach(value => {
var rx = new RegExp(value, 'g');
var match = col_values.join().match(rx);
occurances_dict[value] = match.length;
});
console.info(occurances_dict);
}
ВЫХОД