0

I have an object I want to unflatten and merge certain subElements by the id of child objects. So that instead of 4 objects with duplicate values, I will only have two, and the two will then have a merged subElement array.

So these my interfaces and test cases:

interface ISubElement {
    id: number;
    price: number;
}

interface IElements {
    id: number;
    subElements: ISubElement[];
}

interface IElementCollection {
    elements: IElements[];
}

const rawObject: IElementCollection = {
    elements: [
        {
            id: 1,
            subElements: [
                {id: 111, price: 500},
            ],
        },
        {
            id: 1,
            subElements: [
                {id: 222, price: 1000},
            ],
        },
        {
            id: 1,
            subElements: [
                {id: 333, price: 1500},
            ],
        },
        {
            id: 2,
            subElements: [
                {id: 123, price: 700},
            ],
        },
    ],
};

const expected: IElementCollection = {
    elements: [
        {
            id: 1,
            subElements: [
                {id: 111, price: 500},
                {id: 222, price: 1000},
                {id: 333, price: 1500},
            ],
        },
        {
            id: 2,
            subElements: [
                {id: 123, price: 700},
            ],
        },
    ],
};

This is the function I came up with:

const mergeSubElements = (rawCollection: IElementCollection) => {
    let mergedCollection: IElementCollection = <IElementCollection> {
        elements: [],
    };

    rawCollection.elements.forEach((element: IElements) => {
        console.log('iterating', JSON.stringify(element, null, 4));
        const existing = mergedCollection.elements.find((existingElement: IElements) => {
            return existingElement.id === element.id;
        });

        if (existing) {
            console.log('should add to existing', JSON.stringify(existing, null, 4));
            existing.subElements.concat(element.subElements);
            return;
        }

        mergedCollection.elements.push(element);
    });

    console.log(JSON.stringify(mergedCollection, null, 4));

    return mergedCollection;
};

It seems my problem is that array.prototype.find only gets me the object as value and not as a reference, as even though I concat fields, they won't be inside the mergedCollecton.

How do I find an object in typescript rather per reference than value?

Here's my mocha test case:

describe('it should merge subElements for each element by id', () => {
    it('this shall merge', () => {

        return expect(mergeSubElements(rawObject)).to.deep.equal(expected);
    });
});
0

1 Answer 1

1
existing.subElements = existing.subElements.concat(element.subElements);

It's not that find won't return an object by reference, the issue was with concat:

The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

var arr3 = arr1.concat(arr2);
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.