Jon Phillips
Jon Phillips

Reputation: 21

How to perform array operations in Google App Script?

I'm pretty new to AppScript and I have absolutely no idea how to manipulate arrays. I just want to be able to take one array and collapse the common elements in a separate array as follows;

groceryArray = [
                ["fruit", "apple"],
                ["fruit", "banana"], 
                ["veg", "potato"], 
                ["veg", "onion"], 
                ["veg", "broccoli"],
               ]

and turn that into this...

groceryArray2 = [
                  ["fruit", ["apple", "banana"]], 
                  ["veg", ["potato", "onion", "broccoli"]],
                 ]

I would of thought it's fairly straightforward but I can't work it out at all...

Upvotes: 0

Views: 116

Answers (2)

0Valt
0Valt

Reputation: 10375

What you actually want to achieve is fold a grid over the first column of each row. In a nutshell, this is a very simple algorithmic problem:

  1. Iterate over grid rows, for each row check if the property exists and is an array:

    1. If yes, push the new item into the array.
    2. If no, set the property to be an array with one current item.

TheMaster's answer demonstrates one approach, below is an alternative one (they both follow the same algorithm) using for...of, simple dictionary, and Object.entries:

const groceryArray = [
  ["fruit", "apple"],
  ["fruit", "banana"],
  ["veg", "potato"],
  ["veg", "onion"],
  ["veg", "broccoli"],
];

const fold = (grid, col = 0) => {

  const folded = {};

  for(const [ cat, item ] of grid) {
    const existing = folded[cat];
    
    if(existing) {
      existing.push(item);
      continue;
    }
    
    folded[cat] = [ item ];
  }
  
  return Object.entries(folded);
};

console.log( fold(groceryArray) );

Upvotes: 2

TheMaster
TheMaster

Reputation: 50914

Create a Map and reduce the array:

/*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/
const groceryArray = [
            ["fruit", "apple"],
            ["fruit", "banana"], 
            ["veg", "potato"], 
            ["veg", "onion"], 
            ["veg", "broccoli"],
           ],
  collapsedMap = groceryArray.reduce((m,[category,item]) => m.set(category, m.has(category) ? m.get(category).concat(item):[item]),new Map),
  collapsedArray = [...collapsedMap];
console.info({collapsedMap,collapsedArray});
<!-- https://meta.stackoverflow.com/a/375985/ -->    <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

Upvotes: 2

Related Questions