Sorting of a json based on a group

Viewed 85

I have a JSON which I am trying to sort based on parent-child relation, I need to sort the JSON such that it should ignore the child and consider only the parent for the sorting but after sorting the child should be always next to its respective parent. In JSON I am using "groupType" to define the parent-child relationship. Here is what I have tried.

Fiddle Link

Note: We are free to modify the JSON property to define parent-child relationship.

Input
    George  279
      George_child_a  202
      George_child_b  50
    Hilary  44
    Joe 12
      Joe_child_a 22
    
    
    After sorting alphabatically
    
    Actual Result
    
      Joe_child_a 22
    Joe 12
    Hilary  44
      George_child_b  50
      George_child_a  202
    George  279
    
    Expected Result alphabetically desc or asc
    
    Joe 12
      Joe_child_a 22
    Hilary  44
    George  279
      George_child_b  50
      George_child_a  202

Javascript

    function sortResults(prop, asc) {
        arr.sort(function(a, b) {
            if (asc) {
                return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
            } else {
                return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
            }
        });
        renderResults();
    }

var arr = [
        {
            f_name: 'George',
             age: 279,
            groupType:'A'
        },
        {
            f_name: 'George_child_a',
             age: 202,
            groupType:'A_1'
        },
        {
            f_name: 'George_child_b',
             age: 50,
            groupType:'A_2'
        },{
            f_name: 'Joe',
             age: 12,
            groupType:'B'
        },
        {
            f_name: 'Joe_child_a',
             age: 22,
            groupType:'B_1'
        },
        {
            f_name: 'Hilary',
             age: 44,
            groupType:'C'
        }
    ];
1 Answers

var arr = [
    {
        f_name: 'George',
        age: 279,
        group:'A'
    },
    {
        f_name: 'George_child_a',
        age: 202,
        parent:'A'
    },
    {
        f_name: 'George_child_b',
        age: 50,
        parent:'A'
    },{
        f_name: 'Joe',
        age: 12,
        group:'B'
    },
    {
        f_name: 'Joe_child_a',
        age: 22,
        parent:'B'
    },
    {
        f_name: 'Hilary',
        age: 44,
        group:'C'
    }
];
let tempObj = {};
let mappedArr = [];
function sortResults(sortArr, prop, asc) {
    sortArr.sort(function(a, b) {
        if (asc) {
            return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
        } else {
            return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
        }
    });
}
function groupChild(){
mappedArr = [];
    arr.forEach((ele)=>{
        if (ele.group) {
            tempObj[ele.group] = {...ele, child: []};
        } else if (ele.parent) {
            tempObj[ele.parent].child.push(ele)
        }
    });
    Object.keys(tempObj).forEach((key)=>{
        sortResults(tempObj[key].child,"f_name", false);
        mappedArr.push(tempObj[key]);
    })
}
function sortComp(attr, asc){
groupChild();
sortResults(mappedArr,attr,asc);
renderResults();
}
sortComp('f_name',false);
function renderResults () {
    var html = '';
    for (let e of mappedArr) {
        html += `<tr>
            <td class='${e.group}'>${e.f_name}</td>             
            <td class=${e.group}>${e.age}</td>
            </tr>`;
        for(let ch of e.child){
          html += `<tr>
            <td class='${ch.parent}_child'>${ch.f_name}</td>             
            <td class=${ch.parent}>${ch.age}</td>
            </tr>`;
        }
    }
    $('#results').html(html);
}

$(function() {
    $('#headings th').on('click', function() {
        var attr = $(this).attr('data-attr');
        var asc = (!$(this).attr('data-asc')); // switch the order, true if not set
        
        // clear any previous sort order indicators
        $('#headings th').each(function() {
            $(this).removeAttr('data-asc');
        });
        // set sort order indicator
        if (asc) {
            $(this).attr('data-asc', 'asc');
        }

        sortComp(attr, asc);
    });
        
    renderResults();
});
table {
    margin: 3px;
}
table th {
    font-weight: bold;
    cursor: pointer;
}
table th, table td {
    padding: 3px;
    border: 1px solid #000;
}
.A_child, .A_child, .B_child{
padding-left: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click on the table headings to sort the results.
<table>
    <thead id="headings">
        <tr>
            <th data-attr="f_name">First Name</th>
            <th data-attr="age">Age</th>
        </tr>
    </thead>
    <tbody id="results">
        <!-- this will be auto-populated -->
    </tbody>
</table>

Related