toHo
toHo

Reputation: 438

Sort object based on another object

I have following array generated from HTML structure:

const sort = [{ section_id: 'b', children: ['2'] }, { section_id: 'a', children: ['1', '3'] }]

each object in this array represents a section, where children is an array of content ids belonging to that section.

There is also a product object:

const product = {
            id: 'asd',
            title: 'product title',
            sections: [
                { id: 'a', title: 'section with id a', contents: [{ id: '1' }] },
                { id: 'b', title: 'section with id b', contents: [{ id: '2' }, { id: '3' }] }
            ]
}

I would like to "re-create" product object based on data coming from sort, so the result in this example would be like so:

const sortedProduct = {
            id: 'asd',
            title: 'product title',
            sections: [
                { id: 'b', title: 'section with id b', contents: [{ id: '2' }] },
                { id: 'a', title: 'section with id a', contents: [{ id: '1' }, { id: '3' }] }
            ]
}

I have wrote following function to accomplish just that but first section contains all contents in correct order, rest is just repeat of first one. Please point me to what i'm doing wrong.

const SrtProduct = () => {
    const sort = serializeSections() // returns array as in example
    let sortedProduct = {}
    sortedProduct.sections = []
    const emptySection = {
        _id: '',
        contents: [],
        title: ''
    }
    Object.keys($productStore).forEach(key => {
        if(key !== 'sections') sortedProduct[key] = product[key]
    })

    sort.forEach((section, index) => {
        sortedProduct.sections[index] = emptySection
        let pozycja = getIndex(product.sections, section.id)
        Object.keys(product.sections[index]).forEach(key => {
            if(key !== 'contents') sortedProduct.sections[index][key] = product.sections[pozycja][key]
        })

        if(section.children.length > 0) section.children.forEach((content_id, ind) => {
            let poz = getContentIndex(product.sections, content_id)
            let tmp = sortedProduct.sections[index]
            tmp.contents.push(product.sections[poz[0]].contents[poz[1]])
            sortedProduct.sections[index] = tmp
        })
    })

    return sortedProduct
}

Above code returns:

...
sections: [
                { id: 'a', title: 'section with id a', contents: [{id: '2'}, {id: '1'}, {id: '3'}] },
                { id: 'b', title: 'section with id b', contents: [{id: '2'}, {id: '1'}, {id: '3'}] }
            ]

Helper functions getIndex and getContentIndex both work correctly.

getIndex returns position in array where section with given id is found. ex. getIndex(product.sections, 'b') would return 1

getContentIndex ex. getContentIndex(product.sections, '2') would return [1,0] (section position 1, content position 0)

Input: product, sort

Output sortedProduct which is product with rearranged sections and contents according to information from sort

Upvotes: 0

Views: 87

Answers (1)

PRAJIN PRAKASH
PRAJIN PRAKASH

Reputation: 1475

I found some mistakes in your code, section.id will be undefined because you are looping over sort it only have section_id no id, any way I rewritten your code to get the expected out put .

const SrtProduct = () => {
    const sort = [{ section_id: 'b', children: ['2'] }, { section_id: 'a', children: ['1', '3'] }]; // returns array as in example
    const $productStore ={
            id: 'asd',
            title: 'product title',
            sections: [
                { id: 'a', title: 'section with id a', contents: [{ id: '1' }] },
                { id: 'b', title: 'section with id b', contents: [{ id: '2' }, { id: '3' }] }
            ]
};
    let sortedProduct = Object.assign({}, $productStore);
    sortedProduct.sections=[];
    // const emptySection = {
    //     _id: '',
    //     contents: [],
    //     title: ''
    // }

    sort.forEach((section, index) => {
        // sortedProduct.sections[index] = emptySection
        let product_sections_index = $productStore.sections.findIndex(x => x.id ===section.section_id);
        sortedProduct.sections[index] = $productStore.sections[product_sections_index]

        // Object.keys(product.sections[index]).forEach(key => {
        //     if(key !== 'contents') sortedProduct.sections[index][key] = product.sections[pozycja][key]
        // })
        sortedProduct.sections[index].contents = [];
        section.children.forEach((value,index2) => {
            sortedProduct.sections[index].contents[index2] = {id: value};
        })
        // if(section.children.length > 0) section.children.forEach((content_id, ind) => {
        //     let poz = getContentIndex(product.sections, content_id)
        //     let tmp = sortedProduct.sections[index]
        //     tmp.contents.push(product.sections[poz[0]].contents[poz[1]])
        //     sortedProduct.sections[index] = tmp
        // })
    })

    return sortedProduct
};

you can see/run the code here

Upvotes: 1

Related Questions