Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active February 16, 2021 15:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save barneycarroll/da329fd2f6253f327bbc1dbae493a595 to your computer and use it in GitHub Desktop.
Save barneycarroll/da329fd2f6253f327bbc1dbae493a595 to your computer and use it in GitHub Desktop.
A function for splitting an array or object into several others
export default function split(subject, visitor){
const isArray = Array.isArray(subject)
const container = []
void (isArray ? subject : Object.entries(subject)).forEach(function(entry){
const division = visitor.apply(this, arguments)
if(!(division in container))
container[division] = []
container[division].push(entry)
})
return (
isArray
?
container
:
container.map(Object.fromEntries)
)
}

Split consumes a subject which is an array¹ or plain object², and a visitor function. The visitor is called for each item in the subject, with the signature (value, index, host)¹ or ([key, value], index, hostEntries)², and should return an integer indicating a group the item belongs to; Split returns an array whose contents are the groups consisting of the items for which the visitor returned that index, each group being of the same type as the subject (array or plain object).

Eg:

const [odd, even] = split(
  [9, 4, 6, 7, 2, 3],
  
  x => x % 2 ? 0 : 1,
)

// odd  == [4, 6, 2]
// even == [9, 7, 3]

const [events, other] = split(
  {
    onclick  : () => {},
    onchange : () => {},
    config  : {},
    initial : true,
  },
  
  // 👇 Signature exposes [key, value] as first argument
  ([key]) => key.startsWith('on') ? 0 : 1,
)

// events == {onclick, onchange}
// other  == {config, initial}

Demo here

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