What is the javascript equivalent of numpy argsort?
You can use a Schwartzian transform also known as Decorate-Sort-Undecorate (DSU) in python.
DSU:
- Decorate - Use Array#Map to enrich each item in the array with the needed sort data
- Sort - sort using the added data
- Undecorate - extract the sorted data using Array#map again
Demo:
const dsu = (arr1, arr2) => arr1 .map((item, index) => [arr2[index], item]) // add the args to sort by .sort(([arg1], [arg2]) => arg2 - arg1) // sort by the args .map(([, item]) => item); // extract the sorted itemsconst clickCount = [5,2,4,3,1];const imgUrl = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg'];const result = dsu(imgUrl, clickCount); console.log(result);
thanks to dankal444 for the refactor to the function
For completeness, here's my solution to the actual answer (providing argsort
function), by expanding on Ori's answer with DSU.Since sort is by default taking the first element, so implementing it as DSU is merely adding an index, sorting it, then taking the indices.
let decor = (v, i) => [v, i]; // set index to valuelet undecor = a => a[1]; // leave only indexlet argsort = arr => arr.map(decor).sort().map(undecor);clickCount = [5, 2, 4, 3, 1]imgUrl = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg']order = argsort(clickCount);newArray = order.map(i => imgUrl[i])console.log(newArray);
Functional approach (like @Ori Drori's code) is always a charm to watch, but in this case, you only need to re-arrange an array's items. I believe that there is a simpler way to go and is a much easier code to read.
const clickCount = [5,2,4,3,1];const imgUrl = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg'];sortByArrayRefOrder = (data, orderRefArr) => { let orderedArr = [], i=0; orderRefArr.map( o => { orderedArr[o-1] = data[i++]}); return orderedArr.reverse();}console.log ( sortByArrayRefOrder(imgUrl, clickCount) );