1

I have an array of objects in this format:

const arr = [
    {
        parentKey: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringA',
            myKey3: false,
            myKey4: true
        },
        anotherKey: {}
    },
    {
        parentKey: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringA',
            myKey3: true,
            myKey4: false
        },
        anotherKey: {}
    },
    {
        parentKey: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringA',
            myKey3: true,
            myKey4: false
        },
        anotherKey: {}
    },
    {
        parentKey: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringA',
            myKey3: true,
            myKey4: true
        },
        anotherKey: {}
    },
    {
        parentKey: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringB',
            myKey3: true,
            myKey4: true
        },
        anotherKey: {}
    },
    {
        parentKey: {
            myKey1: 'someStringB',
            myKey2: 'anotherStringB',
            myKey3: false,
            myKey4: true
        },
        anotherKey: {}
    }
];

And I need to get a result in this format:

const result = [
    {
        props: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringA',
            myKey3: false,
            myKey4: true
        },
        entries: [
            {
                parentKey: {
                myKey1: 'someStringA',
                myKey2: 'anotherStringA',
                myKey3: false,
                myKey4: true
                },
                anotherKey: {}
            }
        ] 
    },
    {
        props: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringA',
            myKey3: true,
            myKey4: false
        },
        entries: [
            {
                parentKey: {
                myKey1: 'someStringA',
                myKey2: 'anotherStringA',
                myKey3: true,
                myKey4: false
                },
                anotherKey: {}
            },
            {
                parentKey: {
                    myKey1: 'someStringA',
                    myKey2: 'anotherStringA',
                    myKey3: true,
                    myKey4: false
                },
                anotherKey: {}
            }
        ] 
    },
    {
        props: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringA',
            myKey3: true,
            myKey4: true
        },
        entries: [
            {
                parentKey: {
                    myKey1: 'someStringA',
                    myKey2: 'anotherStringA',
                    myKey3: true,
                    myKey4: true
                },
                anotherKey: {}
            }
        ] 
    },
    {
        props: {
            myKey1: 'someStringA',
            myKey2: 'anotherStringB',
            myKey3: true,
            myKey4: true
        },
        entries: [
            {
                parentKey: {
                    myKey1: 'someStringA',
                    myKey2: 'anotherStringB',
                    myKey3: true,
                    myKey4: true
                },
                anotherKey: {}
            }
        ] 
    },
    {
        props: {
            myKey1: 'someStringB',
            myKey2: 'anotherStringB',
            myKey3: false,
            myKey4: true
        },
        entries: [
            {
                parentKey: {
                    myKey1: 'someStringB',
                    myKey2: 'anotherStringB',
                    myKey3: false,
                    myKey4: true
                },
                anotherKey: {}
            }
        ] 
    }
];

I am trying to write a function groupArray which will group array of object based on array of keys provided, e.g., groupArray(arr, ['parentKey.myKey1', 'parentKey.myKey2', 'parentKey.myKey3', 'parentKey.myKey4']) but haven't succeeded. Here is the jsfiddle with my code. All entries are currently placed in resulting array without being grouped.

Could you give me hint how to fix my function.

2
  • Hi not sure what you mean, are you trying to group the objects together? The result format you provided just restructures the original list with no grouping Commented Aug 4, 2017 at 6:39
  • The entries are grouped by the keys provided. If you check the result you will see that second object of the result includes 2 objects from the original array arr. I am trying to archive something similar to what group-array package does but without nesting. Commented Aug 4, 2017 at 6:49

1 Answer 1

1

You could use a hash table for grouping the same group and a function for getting a value out of an object with it's path through the nested properties.

function groupArray(array, keys) {
    function getValue(object, path) {
        return path.split('.').reduce((o, k) => (o || {})[k], object);
    }

    var hash = Object.create(null),
        result = [];

    array.forEach(function (o) {
        var key = keys.map(k => getValue(o, k)).join('|');
        if (!hash[key]) {
            hash[key] = { props: Object.assign(...keys.map(k => ({ [k.split('.').pop()]: getValue(o, k) }))), entries: [] };
            result.push(hash[key])
        }
        hash[key].entries.push(o);
    });
    return result;
}

var array = [{ parentKey: { myKey1: 'someStringA', myKey2: 'anotherStringA', myKey3: false, myKey4: true }, anotherKey: {} }, { parentKey: { myKey1: 'someStringA', myKey2: 'anotherStringA', myKey3: true, myKey4: false }, anotherKey: {} }, { parentKey: { myKey1: 'someStringA', myKey2: 'anotherStringA', myKey3: true, myKey4: false }, anotherKey: {} }, { parentKey: { myKey1: 'someStringA', myKey2: 'anotherStringA', myKey3: true, myKey4: true }, anotherKey: {} }, { parentKey: { myKey1: 'someStringA', myKey2: 'anotherStringB', myKey3: true, myKey4: true }, anotherKey: {} }, { parentKey: { myKey1: 'someStringB', myKey2: 'anotherStringB', myKey3: false, myKey4: true }, anotherKey: {} }],
    result = groupArray(array, ['parentKey.myKey1', 'parentKey.myKey2', 'parentKey.myKey3', 'parentKey.myKey4']);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.