I am trying to return the second and third value in an array - but struggling to do so with my limited JS knowledge.
I have two arrays which are combined into one and looks like this:
"0.003839795 - clothes ,0.171756425 - food",0.00741361072561247 - electronics"
I want to order the array by highest score, and then pull back the score and the category into separate variables.
category1 = value
category1score = value
cat2 score = value
cat2 score = value
The script below works and can return the top product name, but I can't work out how to make it return the associated score or the second and third prod/scores in the array...
var product;
var finalString=","+user.get('array1')+user.get('array2');
var finalArray = finalString.split(',');
product = finalArray.sort()[finalArray.length - 1] +' - ';
return product.split(' - ')[1];
The output for above array would look like:
cat1 = food
cat1score = 0.171756425
cat2 = electronics
cat2score = 0.00741361072561247
cat3= clothes
cat3score = 0.003839795
Here is an approach that uses a temporary array of objects, and sorts by a field in the object. The parsing provides some flexibility for optional spaces. It also converts the score to a float to ensure leading zeros, negative signs, etc, do not cause inaccurate ordering.
const data = `0.003839795 - clothes ,0.171756425 - food ,0.00741361072561247 - electronics`
let items = [];
const parts = data.split(/\s*,\s*/)
parts.forEach(function (part) {
const pair = part.split(/\s*-\s*/);
items.push({
score: parseFloat(pair[0]),
name: pair[1]
});
})
// sort by score, descending
items.sort(function (a, b) { return b.score - a.score });
for (let i = 0; i < items.length; i++) {
console.log('cat' + (i+1) + '= ' + items[i].name);
console.log('cat' + (i+1) + 'score= '+ items[i].score);
}
Here is your updated snippet. You need to sort and then reverse. And change the order of some of your logic.
var product;
var finalString = `,,,0.003839795 - clothes ,0.171756425 - food ,0.00741361072561247 - electronics`
var finalArray = finalString.split(',');
finalArray.sort().reverse()
finalArray = finalArray.filter(function(it) {
return it.trim().length > 0
})
var rets=[];
for (var i = 0; i < finalArray.length; i++) {
var product = finalArray[i]
var pair = product.split(' - ');
var ret = {
product: pair[1],
score: pair[0]
}
rets.push(ret)
console.log(ret)
}
If I understand your question correctly, you begin with this input:
const arr = [
'0.003839795 - clothes',
'0.171756425 - food',
'0.00741361072561247 - electronics'
// ...
];
From there, you want to first sort the array in descending order (highest to lowest), then transform (map) the output into the below output order:
cat1 = food
cat1score = 0.171756425
cat2 = electronics
cat2score = 0.00741361072561247
cat3 = clothes
cat3score = 0.003839795
You can map => sort => reverse => format values using composable functions:
const arr = [
'0.003839795 - clothes',
'0.171756425 - food',
'0.00741361072561247 - electronics'
// ...
];
const toTuples = val => val.split(' - ');
const floatSort = (a, b) => parseFloat(a[0]) - parseFloat(b[0]);
const toOutputFormat = (tuple, index) => `
cat${index + 1} = ${tuple[1]}
cat${index + 1}score = ${tuple[0]}
`
arr.map(toTuples).sort(floatSort).reverse().map(toOutputFormat);
// initializing categories
categories = ["Food", "Electronics", "Cloths"];
// initializing scores
scores = [0.171, 0.0074, 0.0038];
// constructing array or array with categories and scores
out = [];
categories.forEach(function(d, i){
out.push([d, scores[i]]);
});
// sorting out array based on the score
out.sort(function(x, y) {
return y[1]-x[1];
});
Here is the code for you.
I have used to arrays then merged it into one ans then sorted the merged array on the basis of score.
Here's one thing that you can do:
consider this is your array:
let arr = ["0.003839795 - clothes" ,"0.171756425 - food","0.00741361072561247 - electronics"];
You can split each item of the array into two individual arrays per item.
So basically:
"0.003839795 - clothes" becomes ["0.003839795","clothes"]
This code snippet will do that:
let splittedArray = arr.map((value) => {
return value.split('-').map((v) => v.trim());
});
Now you can just sort them with this logic:
splittedArray.sort((x, y) => y[0] - x[0]);
Now, the array is sorted in ascending order and looks something like this:
[
[
"0.171756425",
"food"
],
[
"0.00741361072561247",
"electronics"
],
[
"0.003839795",
"clothes"
]
]
Now, you can just take out values out of this sorted array simply this way:
cat1 = splittedArray[0][1];
cat1score = splittedArray[0][0];
cat2 = splittedArray[1][1];
cat2score = splittedArray[1][0];
cat3= splittedArray[2][1];
cat3score = splittedArray[0][0];
You can also write these in a simple for loop and get this task done^
Related
I am trying to get an array of strings from another array of strings with following conditions :-
1: Should contain concatenation of first letter of the word at the first index of array with all other elements EX - ["AH", "BEE", "JAMES"] --> ["ABEEJAMES"]
2: Should contain concatenation of first letter of the word at the first and second index of array with all other elements EX - ["AH", "BEE", "JAMES"] --> ["ABJAMES"]
This needs to be done till the last index of the array
Input array of strings
const updateFullNameParts = ["AH", "BEE", "JAMES"];
Current implementation
const noSpaceName = updateFullNameParts.join("");
const createCombination = fullNameParts.map((name) => {
const fullNamePartsCopy = fullNameParts;
const innerResult = fullNamePartsCopy.map((nameCopy) => {
let innerCopy = "";
for (let i = 0; i < fullNamePartsCopy.length; i++) {
if (name === fullNamePartsCopy[i]) {
innerCopy = innerCopy + fullNamePartsCopy[i];
} else if (nameCopy === fullNamePartsCopy[i])
innerCopy = innerCopy + fullNamePartsCopy[i];
else innerCopy = innerCopy + fullNamePartsCopy[i].slice(0, 1);
}
return innerCopy;
});
Expected array of strings
["ABEEJAMES", "ABJAMES", "ABJ", "AHBJAMES", "ABEEJ", "AHBEEJAMES", "AHBEE"]
Array should not contain
["BJAMES", "AB", "BAJAMES", "A"]
Basically the array should only contain combinations in the order of index.
Is there a low time complexity solution for this?
First make list from each word. (first letter and whole word).
Then create list of possible words using couple of forEach loops.
const updateFullNameParts = ["AH", "BEE", "JAMES"];
const list = (arr) => {
let output = [""];
arr.forEach((word) => {
const items = [word[0], word];
const temp = [];
output.forEach((xx) => items.forEach((yy) => temp.push(`${xx}${yy}`)));
output = [...temp];
});
// Add special cases.
// First word and second word
output.push(arr.slice(0, 2).join(''));
return output;
};
console.log(list(updateFullNameParts));
Another variant and simplified with reduce
const arr = ["AH", "BEE", "JAMES"];
const list = arr.reduce(
(acc, word) => [word[0], word].flatMap((yy) => acc.map((xx) => `${xx}${yy}`)),
[""]
);
console.log(list);
I'm trying to make an average array of a bigger and dynamic array. Simpler looks like this:
const bigArr = [[[1,1,1], [2,2,2], [3,3,3]],[[3,3,3], [4,4,4], [7,7,7]]]
in the end, I'm expecting to get:
const averageArray = [[2,2,2], [3,3,3], [5,5,5]]
I know the best way is to triple loop over this array's, but I couldn't manage to get expected result.
averageArray[0][0] is an average of bigArr[0][0] and bigArr[1][0].
There are a few ways to do it (for loops, reduce, etc.) here I show an example with reduce:
const bigArr = [
[[1,1,1], [2,2,2], [3,3,3]],
[[3,3,3], [4,4,4], [7,7,7]],
//[[5,5,5], [6,6,6], [11,11,11]]
];
const averageArray = bigArr.reduce((aggArr, arr, i) => {
if (i == 0){
return arr.map( a => a );
}
else {
arr.forEach( (a, j) => {
a.forEach( (b, k) => {
aggArr[j][k] = ((aggArr[j][k] * i) + b) / (i + 1)
})
});
}
return aggArr;
}, []);
console.log(averageArray);
Output:
[[2,2,2], [3,3,3], [5,5,5]]
It would also work with a larger input like this:
const bigArr = [
[[1,1,1], [2,2,2], [3,3,3]],
[[3,3,3], [4,4,4], [7,7,7]],
[[5,5,5], [6,6,6], [11,11,11]]
];
We get this output:
[[3,3,3], [4,4,4], [7,7,7]]
One final example:
It would also work with a larger input with non identical sub-arrays like this (to illustrate how the averaging is occurring):
const bigArr = [
[[1,2,3], [1,2,3], [1,2,3]],
[[3,4,7], [3,4,7], [3,4,7]],
[[5,6,11], [5,6,11], [5,6,11]]
];
We get this output:
[[3,4,7], [3,4,7], [3,4,7]]
I have an array with values
myarray=["Mark:40", "John:20", "Sofia: 60", "Mark:30"]
desiredArray=["Mark:70", "John:20", "Sofia: 60"]
It should check whether the names are unique and if it found same name multiple times, it should add the marks and make the desired array with distinct elements. I am able to get unique array but not able to merge the marks. Could anyone help?
You could take a Map for collecting the values and render new strings for the result.
var array = ["Mark:40", "John:20", "Sofia: 60", "Mark:30"],
result = Array.from(
array.reduce(
(m, s) => (([k, v]) => m.set(k, (m.get(k) || 0) + +v))(s.split(/:\s*/)),
new Map
).entries(),
a => a.join(':')
);
console.log(result);
You can group the array by using reduce. Use Object.entries to convert the object into an array and map to form the desired output.
let myarray = ["Mark:40", "John:20", "Sofia: 60", "Mark:30"];
let desiredArray = Object.entries(myarray.reduce((c, v) => {
let [n, a] = v.split(':');
c[n] = c[n] || 0;
c[n] += +a;
return c;
}, {})).map(o => o[0] + ":" + o[1]);
console.log(desiredArray);
You can choose to go with simple for loop also:
var myarray=["Mark:40", "John:20", "Sofia: 60", "Mark:30"];
for(var i=0; i<myarray.length; i++){
var splitVal = myarray[i].split(":");
var nameI = splitVal[0];
var scoreI = parseInt(splitVal[1]);
for(var j=i+1; j<myarray.length; j++){
splitVal = myarray[j].split(":");
var nameJ = splitVal[0];
if(nameI === nameJ){
scoreI += parseInt(splitVal[1]);
myarray.splice(j,1);
}
}
myarray[i] = nameI+":"+scoreI;
}
console.log(myarray);
A simple approach would be to iterate over the new array every time that you would like to add a new value and check whether or not the key exists. If it does increment the value, if not add it.
Here is one solution with a temporary object.
// Initial array
const myarray = ["Mark:40", "John:20", "Sofia: 60", "Mark:30"]
// Temporary object used to calculate values
const desired = {};
for (let value of myarray) {
// Index of the first digit in the string
const separatorIndex = value.indexOf(':') + 1;
// Key is everything before the first digit including the :
let key = value.substr(0, separatorIndex);
// If the key isn't present in the object add it
if (desired[key] === undefined) {
desired[key] = 0;
}
// Add the value of the key to the temporary object
// this combines the values of equal keys
desired[key] += parseFloat(value.substr(separatorIndex));
}
const desiredArray = [];
// Create an array from all values
for (let key in desired) {
desiredArray.push(key + desired[key].toString());
}
console.log(desiredArray);
You can do:
const array = ["Mark:40", "John:20", "Sofia: 60", "Mark:30"];
const temp = array.reduce((a, c, i, arr) => {
const u = c.split(':');
a[u[0]] = a[u[0]] + +u[1] || +u[1];
return a;
}, {});
const result = Object.keys(temp)
.map(u => `${u}:${temp[u]}`);
console.log(result);
I believe what I need are two JavaScript functions. I am receiving a comma separated string that holds two types of data: 1) device name followed by 2) numeric value. These two values are separated by a comma, and each set is also separated by a comma. Example string below:
Device_A,5,Device_C,2,Device_A,10,Device_B,8,Device_B,2,Device_C,7
What I want to do is create two separate functions. The first function finds the unique device names and returns just the names in a comma separated string. The second function would calculate the sum of the numeric values for each device. The expected results from the example string above would return:
Function 1 (Device List):
Device_A, Device_B, Device_C
Function 2 (Sums per Device List):
15,10,9
The lists do not need to return in any particular order as long at they both match up. All I have successfully done at this point is return a list of unique values (including numeric values)... I'm stuck on separating the list, but still referring to device name to sum up all of the values.
Thanks in advance. Let me know if you have any questions!
Matt
You could use an object for collecting the names and count.
This edit contains a shared function and two function for the result in equal order.
function getGrouped(data) {
var array = data.split(','),
temp = Object.create(null),
i = 0;
while (i < array.length) {
temp[array[i]] = (temp[array[i]] || 0) + +array[i + 1] || 0;
i += 2;
}
return temp;
}
function getDevices(data) {
var temp = getGrouped(data);
return Object.keys(temp).sort().join();
}
function getCounts(data) {
var temp = getGrouped(data);
return Object.keys(temp).sort().map(function (k) { return temp[k]; }).join();
}
var data = "Device_A,5,Device_C,2,Device_A,10,Device_B,8,Device_B,2,Device_C,7";
console.log(getDevices(data));
console.log(getCounts(data));
When starting out on a problem like this, I think it's wise to not worry about doing it in a single loop or in a fancy one-liner at first.
A) Start out by defining what data structures you need and how to go from one format to another:
Convert my string of data to a list of keys and values
Somehow group these keys and values based on the key
Sum the values for each group
Return a list of all unique keys
Return a list of all summed values
B) Then, try to see if any of the code you've written has the potential be re-used by other parts of your application and refactor accordingly.
C) Finally, assess if there are performance bottle necks and only if there are, optimize for performance.
A. A function for each step:
// 1. From string to array of keys and values
// You already figured this one out. Split by ","!
const namesAndValuesFromString =
str => str.split(",");
// 2. Grouping by key
// Let's first make pairs:
const deviceValuePairs = devicesAndValues => {
let pair = [];
const pairs = [];
devicesAndValues.forEach(x => {
pair.push(x);
if (pair.length === 2) {
pairs.push(pair);
pair = [];
}
});
return pairs;
};
// Key value pairs are a nice starting point for constructing a grouped object:
const kvpsToDeviceValuesObj = kvps => {
const valuesByDevice = {};
kvps.forEach(([key, value]) => {
value = Number(value);
if (!valuesByDevice[key]) {
valuesByDevice[key] = [];
}
valuesByDevice[key].push(value);
});
return valuesByDevice;
};
// 3. Now, we can get to summing the values arrays
const sumValueArrays = valuesByDevice => {
const summedValuesByDevice = {};
// Loop over the objects entries
Object.entries(valuesByDevice).forEach(
([key, values]) => {
summedValuesByDevice[key] = values
.reduce((a, b) => a + b);
}
);
return summedValuesByDevice;
};
// 4. + 5. Now that we have an object with device ids as keys, and summed values inside, we can retrieve the two lists
const getDevices = Object.keys;
const getSums = Object.values;
// Running the code:
const namesAndValues =
namesAndValuesFromString("A,5,C,2,A,10,B,8,B,2,C,7");
console.log(namesAndValues);
const kvps = deviceValuePairs(namesAndValues);
console.log(kvps);
const valuesByDevice = kvpsToDeviceValuesObj(kvps);
console.log(valuesByDevice);
const sumValues = sumValueArrays(valuesByDevice);
console.log(sumValues);
const devices = getDevices(sumValues);
console.log(devices);
const sums = getSums(sumValues);
console.log(sums);
B. Refactoring!
Once you understand each of those steps, you'll start to see things that can be generalized or combined. That's where the fun starts :)
// UTILITIES
const split = del => arr => arr.split(del);
const toPairs = arr => {
let pair = [];
return arr.reduce(
(pairs, x) => {
pair.push(x);
if (pair.length === 2) {
pairs.push(pair);
pair = [];
}
return pairs;
}, []);
};
const sum = (x, y = 0) => +x + y;
const kvpsToGroups = grouper => kvps =>
kvps.reduce(
(groups, [key, value]) => Object.assign(groups, {
[key]: grouper(value, groups[key])
}), {});
// YOUR APP
const sumGrouper = kvpsToGroups(sum);
const dataSplitter = split(",");
const parseData = str => sumGrouper(toPairs(dataSplitter(str)));
// MAIN
const result = parseData("A,5,C,2,A,10,B,8,B,2,C,7");
console.log("devices:", Object.keys(result));
console.log("sums:", Object.values(result));
another way by regexs
let str = "Device_A,5,Device_C,2,Device_A,10,Device_B,8,Device_B,2,Device_C,7", obj = {}
str.match(/(\w+,[0-9]+)/g).forEach((s) => {
s = s.split(',')
obj[s[0]] = (obj[s[0]] || 0) + (Number(s[1]) || 0)
})
console.log(obj)
Something like this should do it:
var input = "Device_A,5,Device_C,2,Device_A,10,Device_B,8,Device_B,2,Device_C,7";
var output = input.split(',').reduce((accumulator, currentValue, currentIndex, array) => {
accumulator[currentValue] = (accumulator[currentValue] || 0)
+ parseInt(array[currentIndex + 1]);
array.splice(0,1);
return accumulator;
}, {});
console.log(Object.keys(output));
console.log(Object.keys(output).map(k => output[k]));
I have an array of items as follows in Javascript:
var users = Array();
users[562] = 'testuser3';
users[16] = 'testuser6';
users[834] = 'testuser1';
users[823] = 'testuser4';
users[23] = 'testuser2';
users[917] = 'testuser5';
I need to sort that array to get the following output:
users[834] = 'testuser1';
users[23] = 'testuser2';
users[562] = 'testuser3';
users[823] = 'testuser4';
users[917] = 'testuser5';
users[16] = 'testuser6';
Notice how it is sorted by the value of the array and the value-to-index association is maintained after the array is sorted (that is critical). I have looked for a solution to this, tried making it, but have hit a wall.
By the way, I am aware that this is technically not an array since that would mean the indices are always iterating 0 through n where n+1 is the counting number proceeding n. However you define it, the requirement for the project is still the same. Also, if it makes a difference, I am NOT using jquery.
The order of the elements of an array is defined by the index. So even if you specify the values in a different order, the values will always be stored in the order of their indices and undefined indices are undefined:
> var arr = [];
> arr[2] = 2;
> arr[0] = 0;
> arr
[0, undefined, 2]
Now if you want to store the pair of index and value, you will need a different data structure, maybe an array of array like this:
var arr = [
[562, 'testuser3'],
[16, 'testuser6'],
[834, 'testuser1'],
[823, 'testuser4'],
[23, 'testuser2'],
[917, 'testuser5']
];
This can be sorted with this comparison function:
function cmp(a, b) {
return a[1].localeCompare(b[1]);
}
arr.sort(cmp);
The result is this array:
[
[834, 'testuser1'],
[23, 'testuser2'],
[562, 'testuser3'],
[823, 'testuser4'],
[917, 'testuser5'],
[16, 'testuser6']
]
If I understand the question correctly, you're using arrays in a way they are not intended to be used. In fact, the initialization style
// Don't do this!
var array = new Array();
array[0] = 'value';
array[1] = 'value';
array[2] = 'value';
teaches wrong things about the nature and purpose of arrays. An array is an ordered list of items, indexed from zero up. The right way to create an array is with an array literal:
var array = [
'value',
'value',
'value'
]
The indexes are implied based on the order the items are specified. Creating an array and setting users[562] = 'testuser3' implies that there are at least 562 other users in the list, and that you have a reason for only knowing the 563rd at this time.
In your case, the index is data, and is does not represent the order of the items in the set. What you're looking for is a map or dictionary, represented in JavaScript by a plain object:
var users = {
562: 'testuser3',
16: 'testuser6',
834: 'testuser1',
823: 'testuser4',
23: 'testuser2',
917: 'testuser5'
}
Now your set does not have an order, but does have meaningful keys. From here, you can follow galambalazs's advice to create an array of the object's keys:
var userOrder;
if (typeof Object.keys === 'function') {
userOrder = Object.keys(users);
} else {
for (var key in users) {
userOrder.push(key);
}
}
…then sort it:
userOrder.sort(function(a, b){
return users[a].localeCompare(users[b]);
});
Here's a demo
You can't order arrays like this in Javascript. Your best bet is to make a map for order.
order = new Array();
order[0] = 562;
order[1] = 16;
order[2] = 834;
order[3] = 823;
order[4] = 23;
order[5] = 917;
In this way, you can have any order you want independently of the keys in the original array.
To sort your array use a custom sorting function.
order.sort( function(a, b) {
if ( users[a] < users[b] ) return -1;
else if ( users[a] > users[b] ) return 1;
else return 0;
});
for ( var i = 0; i < order.length; i++ ) {
// users[ order[i] ]
}
[Demo]
Using the ideas from the comments, I came up with the following solution. The naturalSort function is something I found on google and I modified it to sort a multidimensional array. Basically, I made the users array a multidimensional array with the first index being the user id and the second index being the user name. So:
users[0][0] = 72;
users[0][1] = 'testuser4';
users[1][0] = 91;
users[1][1] = 'testuser2';
users[2][0] = 12;
users[2][1] = 'testuser8';
users[3][0] = 3;
users[3][1] = 'testuser1';
users[4][0] = 18;
users[4][1] = 'testuser7';
users[5][0] = 47;
users[5][1] = 'testuser3';
users[6][0] = 16;
users[6][1] = 'testuser6';
users[7][0] = 20;
users[7][1] = 'testuser5';
I then sorted the array to get the following output:
users_sorted[0][0] = 3;
users_sorted[0][1] = 'testuser1';
users_sorted[1][0] = 91;
users_sorted[1][1] = 'testuser2';
users_sorted[2][0] = 47;
users_sorted[2][1] = 'testuser3';
users_sorted[3][0] = 72;
users_sorted[3][1] = 'testuser4';
users_sorted[4][0] = 20;
users_sorted[4][1] = 'testuser5';
users_sorted[5][0] = 16;
users_sorted[5][1] = 'testuser6';
users_sorted[6][0] = 18;
users_sorted[6][1] = 'testuser7';
users_sorted[7][0] = 12;
users_sorted[7][1] = 'testuser8';
The code to do this is below:
function naturalSort(a, b) // Function to natural-case insensitive sort multidimensional arrays by second index
{
// setup temp-scope variables for comparison evauluation
var re = /(-?[0-9\.]+)/g,
x = a[1].toString().toLowerCase() || '',
y = b[1].toString().toLowerCase() || '',
nC = String.fromCharCode(0),
xN = x.replace( re, nC + '$1' + nC ).split(nC),
yN = y.replace( re, nC + '$1' + nC ).split(nC),
xD = (new Date(x)).getTime(),
yD = xD ? (new Date(y)).getTime() : null;
// natural sorting of dates
if ( yD )
if ( xD < yD ) return -1;
else if ( xD > yD ) return 1;
// natural sorting through split numeric strings and default strings
for( var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++ ) {
oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];
oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];
if (oFxNcL < oFyNcL) return -1;
else if (oFxNcL > oFyNcL) return 1;
}
return 0;
}
// Set values for index
var users = Array();
var temp = Array();
users.push(Array('72', 'testuser4'));
users.push(Array('91', 'testuser2'));
users.push(Array('12', 'testuser8'));
users.push(Array('3', 'testuser1'));
users.push(Array('18', 'testuser7'));
users.push(Array('47', 'testuser3'));
users.push(Array('16', 'testuser6'));
users.push(Array('20', 'testuser5'));
// Sort the array
var users_sorted = Array();
users_sorted = users.sort(naturalSort);
I'd use map once to make a new array of users,
then a second time to return the string you want from the new array.
var users= [];
users[562]= 'testuser3';
users[16]= 'testuser6';
users[834]= 'testuser1';
users[823]= 'testuser4';
users[23]= 'testuser2';
users[917]= 'testuser5';
var u2= [];
users.map(function(itm, i){
if(itm){
var n= parseInt(itm.substring(8), 10);
u2[n]= i;
}
});
u2.map(function(itm, i){
return 'users['+itm+']= testuser'+i;
}).join('\n');
/*returned value: (String)
users[834]= testuser1
users[23]= testuser2
users[562]= testuser3
users[823]= testuser4
users[917]= testuser5
users[16]= testuser6
*/
If you want to avoid any gaps. use a simple filter on the output-
u2.map(function(itm, i){
return 'users['+itm+']= testuser'+i;
}).filter(function(itm){return itm}).join('\n');
Sparse arrays usually spell trouble. You're better off saving key-value pairs in an array as objects (this technique is also valid JSON):
users = [{
"562": "testuser3"
},{
"16": "testuser6"
}, {
"834": "testuser1"
}, {
"823": "testuser4"
}, {
"23": "testuser2"
}, {
"917": "testuser5"
}];
As suggested, you can use a for loop to map the sorting function onto the array.
Array.prototype.sort() takes an optional custom comparison function -- so if you dump all of your users into an array in this manner [ [562, "testuser3"], [16, "testuser6"] ... etc.]
Then sort this array with the following function:
function(comparatorA, comparatorB) {
var userA = comparatorA[1], userB = comparatorB[1]
if (userA > userB) return 1;
if (userA < userB) return -1;
if (userA === userB) return 0;
}
Then rebuild your users object. (Which will loose you your sorting.) Or, keep the data in the newly sorted array of arrays, if that will work for your application.
A oneliner with array of array as a result:
For sorting by Key.
let usersMap = users.map((item, i) => [i, item]).sort((a, b) => a[0] - b[0]);
For sorting by Value. (works with primitive types)
let usersMap = users.map((item, i) => [i, item]).sort((a, b) => a[1] - b[1]);