Skip to content

Instantly share code, notes, and snippets.

@gtrabanco
Last active June 11, 2024 18:04
Show Gist options
  • Save gtrabanco/7c97bd41aa74af974fa935bfb5044b6e to your computer and use it in GitHub Desktop.
Save gtrabanco/7c97bd41aa74af974fa935bfb5044b6e to your computer and use it in GitHub Desktop.
Object.groupBy polyfill
const hasGroup = typeof Object.groupBy === typeof undefined || typeof Array.groupToMap === typeof undefined || typeof Array.group === typeof undefined;
if (!hasGroup) {
const groupBy = (arr, callback) => {
return arr.reduce((acc = {}, ...args) => {
const key = callback(...args);
acc[key] ??= []
acc[key].push(args[0]);
return acc;
}, {});
};
if (typeof Object.groupBy === typeof undefined) {
Object.groupBy = groupBy;
}
if (typeof Array.groupToMap === typeof undefined) {
Array.groupToMap = groupBy;
}
if (typeof Array.group === typeof undefined) {
Array.group = groupBy;
}
}
// There are better approaches using loops directly instead of reduce
// Example:
console.log(
Object.groupBy(
[1, 2, 3, 4, 5, 6],
(v) => v % 2 === 0 ? 'even': 'odd'
)
);
@mhamlet
Copy link

mhamlet commented Mar 28, 2024

This should not be with prototype. Just Object.groupBy

@gtrabanco
Copy link
Author

This should not be with prototype. Just Object.groupBy

Updated. Thank you.

Can you explain why or give a link to know the explanation? 🙏

@mhamlet
Copy link

mhamlet commented Mar 28, 2024

The original API is without prototype. Link: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy

Here is basic usage from documentation:

Object.groupBy(items, callbackFn)

Anyway, by removing prototype your code works very well. I have used it as a polyfill for Google Chrome >= v116.

@gtrabanco
Copy link
Author

Thank you!

I also update to check first if no defined to avoid forget it as I did in my project 😅

@jdegand
Copy link

jdegand commented Jun 11, 2024

For Safari, you need to use Array.prototype.groupToMap.

And you could also add another check for Array.prototype.group.

@gtrabanco
Copy link
Author

const hasGroup = typeof Object.groupBy === typeof undefined || typeof Array.groupToMap === typeof undefined || typeof Array.group === typeof undefined;
if (!hasGroup) {
  const groupBy = (arr, callback) => {
    return arr.reduce((acc = {}, ...args) => {
      const key = callback(...args);
      acc[key] ??= []
      acc[key].push(args[0]);
      return acc;
    }, {});
  };

  if (typeof Object.groupBy === typeof undefined) {
    Object.groupBy = groupBy;
  }

  if (typeof Array.groupToMap === typeof undefined) {
    Array.groupToMap = groupBy;
  }

  if (typeof Array.group === typeof undefined) {
    Array.group = groupBy;
  }
}

I would do it in this way @jdegand

Thanks for the info =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment