Home > OS >  method to sort custom array of object string with > and <= symbol
method to sort custom array of object string with > and <= symbol

Time:08-27

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);

  • Related