Reputation: 21
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
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:
Iterate over grid rows, for each row check if the property exists and is an array:
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
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