Home > Back-end >  Get Unique Value Based on Multiple Columns from Spreadsheet using Google Apps Script and JavaScript
Get Unique Value Based on Multiple Columns from Spreadsheet using Google Apps Script and JavaScript

Time:06-16

So, Basically what I want is to get unique data from a 2d array where I can pass multiple column values which I have stored in an array. Like I want to get unique based on column 1 and 2 so, I can pass the column value like an array [0, 1] to the function and based on the column array it should return unique value.

I have tried something like this:

function sortFunction(a, b) {
  if (a[0] === b[0]) {  // 0 for column one
    return 0;
  }
  else {
    return (a[0] < b[0]) ? -1 : 1;
  }
}

function getUniqueData_(arr) {
  arr = arr.sort(sortFunction)

  let prevEl;
  const newArr = arr.reduce((prevArr, currentVal) => {
    const idx = prevArr.findIndex(val => val[0] === currentVal[0]);
    if (idx === -1) {
      if (prevEl && prevEl[0] !== currentVal[0]) {
        prevArr.push(currentVal);
      }
    } else {
      prevArr.splice(idx, 1);
    }
    prevEl = currentVal;
    return prevArr;

  }, [])

  console.log(newArr);
  return newArr;
}

Instead of passing column value manually I want to pass it dynamically and multiple columns at the same time which I have stored it in array like [0,1] for column 1 and 2.

CodePudding user response:

function sortData(){
  var columns = [0,2]
  var data = [[1,2,3],[1,2,2],[1,2,3]]
  var temp_arr = [];
  var unique_arr = [];
  var specific_columns_data = getSpecificColumnsData(data, columns)
  for(var i=0;i<specific_columns_data.length;i  ){
    if(specific_columns_data[i].join("")!==""){
      
      if(temp_arr.indexOf(specific_columns_data[i].join(""))==-1){
        unique_arr.push(data[i]);
      }
      temp_arr.push(specific_columns_data[i].join(""))
    }
  }
  Logger.log(unique_arr)
}
function getSpecificColumnsData(data, columns){
  var specific_columns_data = []
  var temp_arr = []
  for(var i=0;i<data.length;i  ){
    temp_arr = []
    for(var j = 0;j<columns.length;j  ){
      if(data[i][j]){
        temp_arr.push(data[i][columns[j]])
      }
    }
    specific_columns_data.push([temp_arr])
  }
  return specific_columns_data;
}

CodePudding user response:

To filter an array to only include specified columns, then filter the results into only unique rows,

Try:

function getUniqueData(arr) {

  const data = /*Your (array of) data to filter*/
  
  // Replace arr values with relevant row data.
  let result = arr.map(col => data.map(row => row[col]))
  // Transpose rows to columns.
  result = result[0].map((col, index) => result.flatMap(row => row[index]))
 
  // Keep only unique rows.
  return [...new Set(
    result.map(JSON.stringify)
  )].map(JSON.parse)

}

The big takeaway is the final block of the code, which is:

  • Converting each row of the array into a string for comparison with JSON.stringify.
  • Removing all duplicates by using new Set() with it's results 'spread' into a new array.
  • Then converting all values back to their original types using JSON.parse.
  • Related