Jim from Princeton
Jim from Princeton

Reputation: 741

Array.prototype.sort() for object pairs

I get a function's results in an array of objects:

let options = [
  {
    "aCol": 0,
    "aRow": 10,
    "bCol": 12,
    "bRow": 4,
    "cCol": 5,
    "cRow": 1,
  },
  {
    "aCol": 4,
    "aRow": 10,
    "bCol": 3,
    "bRow": 4,
    "cCol": 1,
    "cRow": 1,
  },
  {
    "aCol": 4,
    "aRow": 10,
    "bCol": 3,
    "bRow": 0,
    "cCol": 0,
    "cRow": 1,
  }
];

that I want to inspect the value pairs, i.e.:

aCol
aRow

and sort them in ascending order by the number of zeroes am amongst the three pairs. The result should be:

let options = [
  {
    "aCol": 4,
    "aRow": 10,
    "bCol": 3,
    "bRow": 0, // b contains a zero
    "cCol": 0, // c contains a zero
    "cRow": 1,
  },
  {
    "aCol": 0, // a contains a zero
    "aRow": 0,
    "bCol": 12,
    "bRow": 4,
    "cCol": 5,
    "cRow": 1,
  },
  {
    "aCol": 4,  // no zeroes in this object in any of the pairs
    "aRow": 10,
    "bCol": 3,
    "bRow": 4,
    "cCol": 1,
    "cRow": 1,
  },
];

I've been messing around leveraging the zeroes and with shortcutting like this:

options.sort((x,y) => 
  (x.aCol * x.aRow < y.aCol * y.aRow) ||
  (x.bCol * x.bRow < y.bCol * y.bRow) ||
  (x.cCol * x.cRow < y.cCol * y.cRow) 
) 

console.log(...options); 

Upvotes: 0

Views: 79

Answers (2)

Peter Seliger
Peter Seliger

Reputation: 13377

function compareColAndRowZeroCounts(a, b) {

  const productZeroCountA = [
    (a.aCol * a.aRow), (a.bCol * a.bRow), (a.cCol * a.cRow)
  ].filter(num => !num).length;

  const productZeroCountB = [
    (b.aCol * b.aRow), (b.bCol * b.bRow), (b.cCol * b.cRow)
  ].filter(num => !num).length;

  const totalZeroCountA = Object.values(a).filter(num => !num).length;
  const totalZeroCountB = Object.values(b).filter(num => !num).length;

  // ascending order
  return ((productZeroCountA > productZeroCountB) && -1)
    || ((productZeroCountA < productZeroCountB) && 1)
    || ((totalZeroCountA > totalZeroCountB) && -1)
    || ((totalZeroCountA < totalZeroCountB) && 1)
    || 0;
}

const options = [{
  "aCol": 0,
  "aRow": 0,
  "bCol": 12,
  "bRow": 4,
  "cCol": 5,
  "cRow": 1,
}, {
  "aCol": 4,
  "aRow": 10,
  "bCol": 3,
  "bRow": 4,
  "cCol": 1,
  "cRow": 1,
}, {
  "aCol": 4,
  "aRow": 10,
  "bCol": 3,
  "bRow": 0,
  "cCol": 0,
  "cRow": 1,
}];

console.log(
  'options.sort(compareColAndRowZeroCounts)',
  options.sort(compareColAndRowZeroCounts)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Upvotes: 0

Robert
Robert

Reputation: 2753

let options = [
  {
    "aCol": 1,
    "aRow": 10,
    "bCol": 12,
    "bRow": 4,
    "cCol": 0,
    "cRow": 1,
  },
  {
    "aCol": 4,
    "aRow": 10,
    "bCol": 3,
    "bRow": 4,
    "cCol": 1,
    "cRow": 1,
  },
  {
    "aCol": 4,
    "aRow": 10,
    "bCol": 3,
    "bRow": 0,
    "cCol": 0,
    "cRow": 1,
  }
];


const sorted = options.sort((x, y) => {
   const xZeros = +!(x.aCol * x.aRow) + +!(x.bCol * x.bRow) + +!(x.cCol * x.cRow);
   const yZeros = +!(y.aCol * y.aRow) + +!(y.bCol * y.bRow) + +!(y.cCol * y.cRow);
   return yZeros - xZeros
})

console.log(sorted)

works for me test

+!(x.aCol * x.aRow) 

so if multiplication is zero then this invers it to "true" and then "+" transform it to 1;

if multiplication is something more than 0 it invers it to false and then this is 0

Upvotes: 1

Related Questions