Input:
[ { BinRange: '200-300' }
, { BinRange: '1-100' }
, { BinRange: '300-400' }
, { BinRange: '100-200' }
, { BinRange: '>1000' }
, { BinRange: '<=1' }
]
the above array of objects which has binrange tried using loadash not sure how to sort the array to get below output
[ { BinRange: '<=1' }
, { BinRange: '1-100' }
, { BinRange: '100-200' }
, { BinRange: '200-300' }
, { BinRange: '300-400' }
, { BinRange: '>1000' }
]
tried writing custom method but not sure to handle <= and > in array any pointer or solution will be a great help
CodePudding user response:
You can switch on the first character to determine if starts with a <
(min) or a >
(max). Anything else would consider the first number in the range.
const array = [
{ BinRange: "200-300" },
{ BinRange: "1-100" },
{ BinRange: "300-400" },
{ BinRange: "100-200" },
{ BinRange: ">1000" },
{ BinRange: "<=1" },
];
const parseRange = (range) => {
switch (range[0]) {
case '<': return Number.MIN_SAFE_INTEGER;
case '>': return Number.MAX_SAFE_INTEGER;
default: return parseInt(range.split('-')[0], 10);
}
}
array.sort(({ BinRange: a }, { BinRange: b }) => parseRange(a) - parseRange(b));
console.log(array.map(o => JSON.stringify(o)).join('\n'));
.as-console-wrapper { top: 0; max-height: 100% !important; }
CodePudding user response:
You just need to parse the lower limit of the bin to number before the sort.
const array = [
{
BinRange: "200-300",
},
{
BinRange: "1-100",
},
{
BinRange: "300-400",
},
{
BinRange: "100-200",
},
{
BinRange: ">1000",
},
{
BinRange: "<=1",
},
];
const getLowerLimit = ({ BinRange }) => {
if (BinRange.includes("-")) return Number(BinRange.split("-")[0]);
if (BinRange.includes(">")) return Number(BinRange.split(">")[1]) 1;
if (BinRange.includes("<=")) return 0;
throw new Error("Invalid bin");
};
array.sort((binA, binB) => {
return getLowerLimit(binA) <= getLowerLimit(binB) ? -1 : 1;
});
console.log(array);
CodePudding user response:
You could use a sort callback that first categorises values by either starting with <
or by >
or something else (3 categories), and number those categories such that <
is 0, anything else is 1, and >
is 2.
That categorisation you can make in many ways. For instance, for a given object a
it could be:
(2 "><".indexOf(a.BinRange[0])) % 3
In the callback first compare by category. If that is equal for both given values, use numerical comparison with parseInt
(which only looks at a valid prefix of the string):
const data = [{"BinRange": "200-300"},{"BinRange": "1-100"},{"BinRange": "300-400"},{"BinRange": "100-200"},{"BinRange": ">1000"},{"BinRange": "<=1"}];
data.sort((a, b) =>
((2 "><".indexOf(a.BinRange[0])) % 3 - (2 "><".indexOf(b.BinRange[0])) % 3)
|| (parseInt(a.BinRange[0]) - parseInt(b.BinRange[0]))
);
console.log(data);
Another solution could be to remove the >
character when it is found, and replace <=
with a large negative number:
const data = [{"BinRange": "200-300"},{"BinRange": "1-100"},{"BinRange": "300-400"},{"BinRange": "100-200"},{"BinRange": ">1000"},{"BinRange": "<=1"}];
const order = (o) => parseFloat(o.BinRange.replace("<=", "-Infinity").replace(">", ""))
data.sort((a, b) => order(a) - order(b));
console.log(data);