Skip to content

Separates array of objects into sub-arrays of objects with matching property values

License

Notifications You must be signed in to change notification settings

writetome51/get-grouped-by-properties

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

getGroupedByProperties<T>(
     properties: string[],
     objects: T[],
     matchFunctions?: {
          [property: string]: (a, b) => boolean
     }
): Array<T[]>

Returns objects separated into groups (sub-arrays). Each group will contain objects with
matching values of every property in properties. You can customize how a match is determined
with the optional matchFunctions.

matchFunctions: object. Any of its keys must be identical to a property in properties.
The value of each key must be this type of function: (a, b) => boolean . It's called to
determine a match when grouping by the property matching that particular key. If a matching key
isn't provided for a particular property, the default matchFunction
(a, b) => String(a) === String(b) will be used for that property.
You can change the default matchFunction with the key '$default'.

The properties can each contain dot-notation, i.e, 'property.subproperty.subsubproperty'.
Even if a property is an array index, here you need to use dot-notation and not
square braces, i.e. '1.0' // instead of [1][0]
The order you list the properties determines the order the groups are returned in.

Examples

let persons = [
	{name: {first: 'Danny', last: 'Jones'}, address:'800 N. First St.'},
	{name: {first: 'Michael', last: 'Watts'}, address:'100 S. Palm Way'},
	{name: {first: 'Robert', last: 'Walters'}, address:'200 W. Elm St.'},
	{name: {first: 'Sara', last: 'Watts'}, address:'100 S. Palm Way'},
	{name: {first: 'Carol', last: 'Jones'}, address:'800 N. First St.'},
	{name: {first: 'Tara', last: 'Zucko'}, address:'100 S. Palm Way'},
];
getGroupedByProperties(['address', 'name.last'], persons);
/******************
Returns:
 [
    [
       {name: {first: 'Michael', last: 'Watts'}, address: '100 S. Palm Way'},
       {name: {first: 'Sara', last: 'Watts'}, address: '100 S. Palm Way'}
    ],
    [ {name: {first: 'Tara', last: 'Zucko'}, address:'100 S. Palm Way'} ],
    [ {name: {first: 'Robert', last: 'Walters'}, address: '200 W. Elm St.'} ],
    [
       {name: {first: 'Danny', last: 'Jones'}, address: '800 N. First St.'},
       {name: {first: 'Carol', last: 'Jones'}, address: '800 N. First St.'}
    ]
 ]
 ******************/


// Reverse the order of properties to see the result:

getGroupedByProperties(['name.last', 'address'], persons);
/******************
Returns:
 [
    [
       {name: {first: 'Danny', last: 'Jones'}, address: '800 N. First St.'},
       {name: {first: 'Carol', last: 'Jones'}, address: '800 N. First St.'}
    ],
    [ {name: {first: 'Robert', last: 'Walters'}, address: '200 W. Elm St.'} ],
    [
       {name: {first: 'Michael', last: 'Watts'}, address: '100 S. Palm Way'},
       {name: {first: 'Sara', last: 'Watts'}, address: '100 S. Palm Way'}
    ],
    [ {name: {first: 'Tara', last: 'Zucko'}, address:'100 S. Palm Way'} ]
 ]
 ******************/
 

// This example makes matching case-insensitive by default:

persons = [
    { name: { first: 'Danny', last: 'Jones' }, email: '[email protected]' },
    { name: { first: 'michael', last: 'watts' }, email: '[email protected]'},
    { name: { first: 'Michael', last: 'Watts' }, email: '[email protected]' },
    { name: { first: 'danny', last: 'jones' }, email: '[email protected]' }
];
getGroupedByProperties(
    ['name.last', 'email'],
    persons,
    {'$default': (a, b) => a.toLowerCase() === b.toLowerCase()} 
);
/***************
Returns:
[
  [
    { name: { first: 'Danny', last: 'Jones' }, email: '[email protected]' },
    { name: { first: 'danny', last: 'jones' }, email: '[email protected]' }
  ],
  [
    { name: { first: 'Michael', last: 'Watts' }, email: '[email protected]' },
    { name: { first: 'michael', last: 'watts' }, email: '[email protected]' }
  ]
]
 ****************/


// This makes string matching case-insensitive and separates those younger than 100 
// from those 100 and older:

persons = [
	{name: {first: 'Eddie'}, age: 102},
	{name: {first: 'Eddie'}, age: 32},
	{name: {first: 'danny'}, age: 102},
	{name: {first: 'eric'}, age: 25},
	{name: {first: 'Danny'}, age: 31},
	{name: {first: 'David'}, age: 100},
];
getGroupedByProperties(
    // group by first letter of first name, and age:
    ['name.first.0', 'age'],
    persons,
    {
        'name.first.0': (a, b) => a.toLowerCase() === b.toLowerCase(),
        // Separate ages between those younger than 100, and everyone else:
        'age': (a, b) => a < 100 ? b < 100 : b >= 100
    }
);
/***********
Returns:
[
  [ {name: {first: 'Danny'}, age: 31} ],
  [ {name: {first: 'David'}, age: 100},  {name: {first: 'danny'}, age: 102} ],
  [ {name: {first: 'eric'}, age: 25},  {name: {first: 'Eddie'}, age: 32} ],
  [ {name: {first: 'Eddie'}, age: 102} ]
]
***********/

Installation

npm i @writetome51/get-grouped-by-properties

Loading

import {getGroupedByProperties} from '@writetome51/get-grouped-by-properties';

About

Separates array of objects into sub-arrays of objects with matching property values

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published