Как я могу сравнить значения в одном столбце со значениями в других столбцах? - PullRequest
2 голосов
/ 07 марта 2019

Если у меня есть электронная таблица, в которой люди продолжают и оценивают песни (у каждой песни есть свой ряд, а у каждого пользователя свой столбец), как я могу написать скрипт для итерации по каждому столбцу пользователя, а затем сравнить рейтинг отдельного пользователякаждой песни в столбец, который является входом?

Цель состоит в том, чтобы вывести столбец с ранжированием, наиболее похожим на ранжирование входного столбца (в идеале это должна быть итеративная рекурсивная функция с пространственной сложностью O(1) ивременная сложность O(log(n)).

Я бы подумал сделать функцию, которая генерирует формулу для использования, такую ​​как =FINDMOSTSIMILAR(<USER>), которая выводит значение первой строки в столбце вывода, но я не уверенс чего начать. У меня есть некоторый опыт работы с JavaScript, и я знаю, что Google Apps Script основан на JS, но я не знаю, как выполнить эту функцию в GAS.

Электронная таблица

1 Ответ

2 голосов
/ 07 марта 2019

Я пытался дать вам начало. Перейдите на лист, нажмите Инструменты> Редактор скриптов . Вставьте этот код.

Чтобы найти аналогичного пользователя, то, что делает этот код, между входным пользователем и любым другим пользователем, рассчитать различия для рейтингов каждой песни и добавить их для получения значения. Сделайте это для каждого пользователя в листе. Затем найдите наименьшее из различий и выведите, какой пользователь производит это значение. Эта логика разделена в функции compare, и вы можете изменить ее в соответствии со своими потребностями.

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  // Or DocumentApp or FormApp.
  ui.createMenu('Find Similar User')
      .addItem('Similar User', 'showPrompt')
      .addToUi();
}

// this configuration is based on current sheet names and formatting
// if sheet names change, change needed here
// if track title and user columns change, change needed here
var config = {
  // sheet name: [ col of track title, col of 1st user, col of last user ]
  "UV6": [6, 9, 28],
  "Midnight Underground": [7, 11, 28],
  "Furious Fap February": [8, 12, 23],
  "March Masturbation Madness": [7, 11, 31]
};

function showPrompt() {
  var ui = SpreadsheetApp.getUi(); // Same variations.

  var result = ui.prompt(
    'Find similar user.',
      'Enter user name:',
      ui.ButtonSet.OK_CANCEL);

  // Process the user's response.
  var button = result.getSelectedButton();
  var text = result.getResponseText();
  if (button == ui.Button.OK) {
    // User clicked "OK".
    text = text.trim();
    if (!text) return;
    FINDMOSTSIMILAR(text);
  } else if (button == ui.Button.CANCEL) {

  } else if (button == ui.Button.CLOSE) {

  }
}

function FINDMOSTSIMILAR(username) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var aSheet = ss.getActiveSheet();
  var aSheetName = aSheet.getName();

  // get positions from config
  if (!config[aSheetName]) return;
  var userNamesColsStart = config[aSheetName][1];
  var userNamesColsSpan = config[aSheetName][2] - config[aSheetName][1] + 1;
  var titleColStart = config[aSheetName][0];

  // read user names
  var users = aSheet.getRange(1,userNamesColsStart,1,userNamesColsSpan).getValues()[0];
//  Logger.log(users);

  // read title col
  var tArr = aSheet.getRange(2,titleColStart,aSheet.getLastRow()-2,1).getValues();
//  Logger.log(tArr);

  // data structure
  var DS = {};
  users.forEach(function(h, i) {
    var obj = {};
    var colValues = aSheet.getRange(2,userNamesColsStart+i,aSheet.getLastRow()-2,1).getValues();
    tArr.forEach(function(v, i) {
      obj[i] = colValues[i][0];
    });
    DS[h] = obj;
  });
//  Logger.log(DS);

  var target = DS[username];
  delete DS[username];

  var results = [];

  Object.keys(DS).forEach(function(user) {
    var obj = {};
    obj.prop = username+'__'+user;
    obj.value = compare(target, DS[user]);
    results.push(obj);
  });

  // sort based on difference values
  results.sort(comp);
  Logger.log(results);

  // user with lowest difference is answer
  var similarUser = results[0].prop.split('__')[1];
  Logger.log(similarUser);

  try {
    ss.getActiveCell().setValue([similarUser]);
  } catch(e) {}

}

function comp(a, b) {
  if (a.value < b.value) return -1;
  else if (a.value > b.value) return 1;
  else return 0;
}

// this takes a difference of two users ratings for the same song
// accumulate all the differences for all songs into a single value
// change here how to compare 2 song ratings
function compare(target, user) {
  var v = 0;
  Object.keys(target).forEach(function(key, i) {
    v += Math.abs(target[key] - user[key]);
  });
  return v;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...