3
\$\begingroup\$

I have a data representing several elements (that could be rendered at some point as div), composed of y position (property top) and its height (property height).

These elements are always positioned vertically one next/on-top of each others based on their order.

At the moment I am using the following script to calculate their top position accordingly to their height, script works fine but I kindly ask you your revision in order to improve if possible:

  • Adjustment for speed as I would need interaction over thousand of objects.

  • Possibility of an alternative approach to solve this problem if you know any.

Example here, please look at the console for final result http://jsbin.com/xamagidebe/1/

<html xmlns="http://www.w3.org/1999/xhtml">
<head>

    <title></title>
    <style>
    </style>
    <script>
        window.app = {
            data: [
                    { id: 'h', order: 0, top: null, height: 10 },
                    { id: 'c', order: 1, top: null, height: 20 },
                    { id: 'f', order: 2, top: null, height: 30 }
            ],
            start: function () {
                this.data.sort(function (a, b) {
                    if (b.order > a.order) {
                        return 1;
                    }
                });
                var len = this.data.length;
                var i = 0;
                var x = 0;
                var sum = 0;
                while (i < len) {
                    var item = this.data[i];
                    while (x < len) {
                        var itemX = this.data[x];
                        if (itemX.order < item.order) {
                            sum += itemX.height;
                        }
                        x++;
                    }
                    item.top = sum;
                    i++;
                    sum = 0;
                    x = 0;
                }
                this.data.sort(function (a, b) {
                    if (a.order > b.order) {
                        return 1;
                    }
                });
                console.log('after', this.data);
            }
        };

    </script>
</head>
<body onload="window.app.start();">


</body>
</html>
\$\endgroup\$
3
\$\begingroup\$

If you sort your elements ascending by order, you can get rid of the nested loop and just keep a running sum as you loop through:

start: function () {
    // sort ascending by order
    this.data.sort(function (a, b) {
        if (b.order < a.order) {
            return 1;
        }
    });
    var len = this.data.length;
    var i = 0;
    var sum = 0;
    while (i < len) {
        var item = this.data[i];

        // the top of this element is the sum of all previous element's heights
        item.top = sum;

        // don't reset sum here, just keep adding to it
        sum += item.height;
        i++;
    }
    console.log('after', this.data);
}

I have also removed the re-sorting at the end of the function as it is no longer needed due to the initial sort being ascending.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.