i have two array, lets say priceArray= [1,5,3,7]
userIdArray=[11, 52, 41, 5]
i need to sort the priceArray, so that the userIdArray will be also sorted. for
Taken from Sorting with map and adapted for the userIdArray:
// the array to be sorted
var priceArray = [1, 5, 3, 7],
userIdArray = [11, 52, 41, 5];
// temporary array holds objects with position and sort-value
var mapped = priceArray.map(function (el, i) {
return { index: i, value: el };
});
// sorting the mapped array containing the reduced values
mapped.sort(function (a, b) {
return a.value - b.value;
});
// container for the resulting order
var resultPrice = mapped.map(function (el) {
return priceArray[el.index];
});
var resultUser = mapped.map(function (el) {
return userIdArray[el.index];
});
document.write('<pre>' + JSON.stringify(resultPrice, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(resultUser, 0, 4) + '</pre>');
With proper data structure, as rrowland suggest, you might use this:
var data = [{
userId: 11, price: 1
}, {
userId: 52, price: 15
}, {
userId: 41, price: 13
}, {
userId: 5, price: 17
}];
data.sort(function (a, b) {
return a.price - b.price;
});
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');
A bit shorter with ES6
var priceArray = [1, 5, 3, 7],
userIdArray = [11, 52, 41, 5],
temp = Array.from(priceArray.keys()).sort((a, b) => priceArray[a] - priceArray[b]);
priceArray = temp.map(i => priceArray[i]);
userIdArray = temp.map(i => userIdArray[i]);
console.log(priceArray);
console.log(userIdArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }
It's hard to prescribe a better solution without knowing the whole use-case. That said, if you need these sorted by ID, it may make more sense to create a single array that contains user objects:
var users = [
{ id: 123, price: 25.00 },
{ id: 124, price: 50.00 }
];
users.sort(function(a, b) {
return a.id - b.id;
});
Or, if they don't need to be sorted, you can simply create a map of users by id:
var userPrices = {
123: 25.00,
124: 50.00
};
I have seen a nice talk about making impossible state impossible. This covered the 2 arrays that are related but can go out of sync and better to use one array of objects that have 2 properties (as mentioned several times).
However; if you want to mutate both arrays and sort them the same way you can do the following:
//this will mutate both arrays passed into it
// you could return the arrays but then you need to do arr.slice(0).sort(...) instead
const sortSame = sortFn => (arrayToSort,arrayToSortSame) => {
const sortResults = [];
arrayToSort.sort(//will mutate the array
(a,b)=>{
const result = sortFn(a,b);
sortResults.push(result);
return result
}
);
arrayToSortSame.sort(()=>sortResults.shift());
return undefined;
}
const priceArray= [1,5,3,7];
const userIdArray=[11, 52, 41, 5];
const numSortSameAscending = sortSame((a,b)=>a-b);
numSortSameAscending(priceArray,userIdArray);
console.log(
priceArray,userIdArray
)
Even though the code in this answer may look simpler it is not the cheapest way to do it, as mapping is a cheaper operation than sorting (better to map 3 times and sort once then to sort twice) depending on the size of the arrays and how much the original array is out of order this way of sorting same may be very expensive.
Building on Rrowland's answer, you can create the array of objects with a library like lodash:
var prices = [1, 5, 8, 2];
var userIds = [3, 5, 1, 9];
var pairs = _.zipWith(prices, userIds, function(p, u) {
return { price: p, userId: u };
});
This will give you an object like:
[
{ price: 1, userId: 3 },
{ price: 5, userId: 5 },
... etc
]
Then, for sorting, you can simply use a Javascript sort:
pairs.sort(function(p) { return p.price });
If you really need it as an array of userIds, you can get it back, after the sort:
var sortedUserId = pairs.map( function(p) { return p.userId });
// returns [ 3, 9, 5, 8 ];