Assign ranks to objects by values in an array of objects
<p>I have an array of objects like so:</p>

<pre><code>var data = {
    a: [
        { keyone:'c', keytwo: 'anna', keythree: 21, keyfour: 15 },
        { keyone:'a', keytwo: 'anna', keythree: 22, keyfour: 15 },
        { keyone:'s', keytwo: 'anna', keythree: 10, keyfour: 15 },
        { keyone:'v', keytwo: 'anna', keythree: 7, keyfour: 15 }
    ],

    b: [
        { keyone:'f', keytwo: 'any', keythree: 45, keyfour: 100 },
        { keyone:'b', keytwo: 'any', keythree: 146, keyfour: 100 },
        { keyone:'t', keytwo: 'any', keythree: 23, keyfour: 100 },
        { keyone:'h', keytwo: 'any', keythree: 11, keyfour: 100 }
    ]
  };
</code></pre>

<p>I want to assign ranks to each object, based on values of <code>keythree</code> and <code>keyfour</code>, within the groups as well as within the entire data set. How would I do it?</p>

<p>Update: I have depicted the ranks in my code above.</p>

<p>Resultant object:</p>

<pre><code>var data = {
    a: [
        { keyone:'c', keytwo: 'anna', keythree: 21, keyfour: 15, rankgroup: 3, rankall: 4 },

        { keyone:'a', keytwo: 'anna', keythree: 22, keyfour: 15, rankgroup: 4, rankall: 5 },

        { keyone:'s', keytwo: 'anna', keythree: 22, keyfour: 15, rankgroup: 2, rankall: 2 },

        { keyone:'v', keytwo: 'anna', keythree: 7, keyfour: 15, rankgroup: 1, rankall: 1 }
    ],

    b: [
        { keyone:'f', keytwo: 'any', keythree: 45, keyfour: 100 },

        { keyone:'b', keytwo: 'any', keythree: 146, keyfour: 100 },

        { keyone:'t', keytwo: 'any', keythree: 23, keyfour: 100 },

        { keyone:'h', keytwo: 'any', keythree: 11, keyfour: 100 }
    ]
};
</code></pre>

<p>I am using <code>lodash</code>. My idea is to first sort the array based on those keys, then loop over the original object, insert the sorted index by comparing another key. This is what I have tried:</p>

<pre><code>var keys = Object.keys(data);
var result = {};
var numkeys;
for(var i=0; i &lt; keys.length; i++) {
    if(!numkeys) {
        var numkeys = _.keys(_.pick(data[keys[i]][0], _.isNumber));
  }

        for(var j=0;j&lt;numkeys.length;j++) {
    var sorted = _.sortBy(data['a'], numkeys[j]);
        _.forEach(sorted, function(n, k) {

        //THIS FAILS
        var t = _.set(_.where(data[keys[i]], {keyone: n.keyone}), keys[i]+'rank', k);
        console.log(t);
        });

    }
  }
</code></pre>

<p>How would I do it? My logic seems too complex and the <code>set</code> method does not update the original object by key but adds a new entry after the main object.</p>

<p><strong>Update</strong>: Notice the duplicate occurrence of <code>22</code> for the object <code>a</code>. This leads to an issue when assigning ranks, since <code>indexOf</code> will always return the index of the first occurrence, hence the second occurrence will never have an index assigned to it and hence the value will be undefined.</p>