react
May 26, 2019, 6:18pm
#1
I have a large object of key:value
pairs to sort by the value.
I am trying to convert to an array using Object.entries, I believe it results in an array of arrays (rather than an array of objects) so I am trying access the value by using index 1, rather than dot notation:
sortBy = () => {
const countries = this.props.countriesToRender;
const countriesArray = Object.entries(countries);
return countriesArray.sort((a, b) => {
return b[1] - a[1];
});
};
so far it doesn’t work, does this seem the right approach?
One possible way is the following:
sortBy = () => {
const countries = this.props.countriesToRender;
const countriesArray = Object
.keys(countries)
.map(country => ({ [country]: countries[country] }));
return countriesArray.sort((a, b) => {
const aVal = Object.values(a)[0];
const bVal = Object.values(b)[0];
return bVal - aVal;
});
}
It will return an array of objects that looks something like:
[
{ Algeria: 2},
{ Albania: 8 },
{ Afghanistan: 3 }
.
.
.
]
You did not specify what you wanted the objects inside the array to look like, but I assumed the above would work.
const countries = {
Bfghanistan: 3,
Zlbania: 9,
Clgeria: 3
};
const arrOfArrays = Object.entries(countries);
const sorted = arrOfArrays.sort((a, b) => {
return a[0].localeCompare(b[0]);
});
console.log(sorted);
I’m not entirely sure return val1 - val2
works. I think sort requires a return of -1, 1, 0.
https://jsfiddle.net/5Ldnt4h7/
react
May 26, 2019, 7:19pm
#4
Yes, that is exactly how I’d like them to look - thanks!
I’ll try it now, but also think I might need to set state so the sorted array is rendered? Will try it out
@kerafyrm02 The bVal - aVal will work because it is a number and not a string.
Also, the OP mentioned wanted an array of objects and not an array of arrays which yours produces. However, it may be that is fine with the OP.
react
May 26, 2019, 7:21pm
#6
I actually want to sort by the numbers not the names, so will do [1] – using [0] will sort by the names I assume? Will try it.
Oh he’s sorting by the numbers and not sorting the country names alphabetically?
Yes, he wants the countries sorted in descending order by the value and not the name.
react
May 26, 2019, 7:31pm
#10
import React from "react";
class Table extends React.Component {
getCountryNames = () => {
return Object.keys(this.props.countriesToRender);
};
getDeveloperCounts = () => {
return Object.values(this.props.countriesToRender);
};
sortBy = () => {
const countries = this.props.countriesToRender;
const countriesArray = Object.keys(countries).map(country => ({
[country]: countries[country]
}));
return countriesArray.sort((a, b) => {
const aVal = Object.values(a)[0];
const bVal = Object.values(b)[0];
return bVal - aVal;
});
};
render() {
return (
<div>
<table className="ui celled center aligned table">
<thead>
<tr>
<th>Country</th>
<th>
{" "}
<button onClick={() => this.sortBy()}>Developers</button>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
{this.getCountryNames().map(name => {
return <tr>{name}</tr>;
})}
</td>
<td>
{this.getDeveloperCounts().map(count => {
return <tr>{count}</tr>;
})}
</td>
</tr>
</tbody>
</table>
</div>
);
}
}
export default Table;
This is the whole component, I think I’m not feeding the results of the sort into the render properly.
Shouldn’t you be setting state of developers
inside your method sortBy
method?
react
May 26, 2019, 7:37pm
#12
no errors related to the sort
react
May 26, 2019, 7:40pm
#13
No because developers is the raw data, the developerCount is calculated from the countriesToRender method
react
May 26, 2019, 7:41pm
#14
I just tried adding a new state property, with sortBy as a callback to App.js but it didn’t make much difference
Where exactly are you wanting to show this array of objects in some way? Which component?
Gotcha. My error then.
Of course I had to find another way.
const countries = {
Bfghanistan: 2,
Zlbania: 9,
Clgeria: 3
};
const sorted = Object.entries(countries).sort(([c1, v1], [c2, v2]) => {
return v2 - v1;
}).reduce((o, [k, v]) => (o[k] = v, o), {});
console.log(sorted);
react
May 26, 2019, 7:48pm
#17
in the Table.js .
I’ve moved it back up to App.js with a setState
sortBy = () => {
const countries = this.state.countriesToRender;
const countriesArray = Object.keys(countries).map(country => ({
[country]: countries[country]
}));
const sortedCountries = countriesArray.sort((a, b) => {
const aVal = Object.values(a)[0];
const bVal = Object.values(b)[0];
return bVal - aVal;
});
this.setState({ countriesToRender: sortedCountries });
};
kerafyrm02:
const sorted = Object.entries(countries).sort(([c1, v1], [c2, v2]) => { return v2 - v1; }).reduce((o, [k, v]) => (o[k] = v, o), {});
While that works, I am not sure it is very readable.
1 Like
Yeah. Not really readable at all. lol.