0

I have a requirement to sort a object array based on frozenEdge property. If property value is start we should move item to top and property value is end we have to move item to bottom. Item which doesn't have field property are invalid so there position should remain as it ,In below array for example first item is invalid so we should not reorder.

I have tried a sample program which work in firefox but failing in chrome I am looking for a solution which can work in chrome, safari and firefox

Actual Array

[{
  "style": "width: 10px; text-align: center",
  "className": "oj-sm-only-hide table",
  "headerClassName": "Sample"
}, {
  "headerText": "Fee Description",
  "field": "Description"
}, {
  "headerText": "Amount",
  "field": "FeeAmount",
  "frozenEdge": "start"
}, {
  "headerText": "Currency",
  "field": "CurrencyCode",
  "frozenEdge": "start"
}, {
  "headerText": "Status",
  "field": "FeeStatus",
}, {
  "headerText": "Department",
  "field": "DepartmentDescription"
}, {
  "headerText": "Assessed Date",
  "field": "AssessedDate",
  "frozenEdge": "end"
}, {
  "headerText": "Payment Date",
  "field": "PaymentDate"
}, {
  "headerText": "Paid By",
  "field": "PaidBy",
  "frozenEdge": "end"
}, {
  "headerText": "Invoice",
  "field": "Invoice"
}, {
  "headerClassName": "table-header table-row-botton",
  "className": "table-row-botton"
}]

Expected Output

[{
  "style": "width: 10px; text-align: center",
  "className": "oj-sm-only-hide table",
  "headerClassName": "Sample"
}, {
  "headerText": "Amount",
  "field": "FeeAmount",
  "frozenEdge": "start"
}, {
  "headerText": "Currency",
  "field": "CurrencyCode",
  "frozenEdge": "start"
}, {
  "headerText": "Fee Description",
  "field": "Description"
}, {
  "headerText": "Status",
  "field": "FeeStatus",
}, {
  "headerText": "Department",
  "field": "DepartmentDescription"
}, {
  "headerText": "Payment Date",
  "field": "PaymentDate"
}, {
  "headerText": "Invoice",
  "field": "Invoice"
}, {
  "headerText": "Assessed Date",
  "field": "AssessedDate",
  "frozenEdge": "end"
}, {
  "headerText": "Paid By",
  "field": "PaidBy",
  "frozenEdge": "end"
}, {
  "headerClassName": "table-header table-row-botton",
  "className": "table-row-botton"
}]

Working code for Firefox:

function isValidColumn(column, ignoreFR) {
  var retVal = true;
  if (!column.hasOwnProperty('field')) {
    return false;
  }
  return retVal;
}

var array = [{
  "style": "width: 10px; text-align: center",
  "className": "oj-sm-only-hide table",
  "headerClassName": "Sample"
}, {
  "headerText": "Fee Description",
  "field": "Description"
}, {
  "headerText": "Amount",
  "field": "FeeAmount",
  "frozenEdge": "start"
}, {
  "headerText": "Currency",
  "field": "CurrencyCode",
  "frozenEdge": "start"
}, {
  "headerText": "Status",
  "field": "FeeStatus",
}, {
  "headerText": "Department",
  "field": "DepartmentDescription"
}, {
  "headerText": "Assessed Date",
  "field": "AssessedDate",
  "frozenEdge": "end"
}, {
  "headerText": "Payment Date",
  "field": "PaymentDate"
}, {
  "headerText": "Paid By",
  "field": "PaidBy",
  "frozenEdge": "end"
}, {
  "headerText": "Invoice",
  "field": "Invoice"
}, {
  "headerClassName": "table-header table-row-botton",
  "className": "table-row-botton"
}];

array.sort(
  function(col1, col2) {
    if (isValidColumn(col1, true) && isValidColumn(col2, true)) {

      if (col2.hasOwnProperty('frozenEdge') &&
        col2.frozenEdge == 'start') {
        return (col2.frozenEdge === 'start' && col1.frozenEdge !== 'start') ? 1 :
          (col1.frozenEdge === 'start') ? -1 : 0;
      } else if (col1.hasOwnProperty('frozenEdge') &&
        col1.frozenEdge == 'end') {
        return (col1.frozenEdge == 'end' && col2.frozenEdge !== 'end') ? 1 :
          (col1.frozenEdge === 'end') ? -1 : 0;
      } else {
        return 0;
      }
    } else {
      return 0;
    }
  }
);

console.log(array);
.as-console-wrapper { top: 0; max-height: 100% !important; }

0

2 Answers 2

2

You could take an object with the wanted order and check field first.

const
    order = { start: -1, default: 0, end: 1 },
    data = [{ style: "width: 10px; text-align: center", className: "oj-sm-only-hide table", headerClassName: "Sample" }, { headerText: "Fee Description", field: "Description" }, { headerText: "Amount", field: "FeeAmount", frozenEdge: "start" }, { headerText: "Currency", field: "CurrencyCode", frozenEdge: "start" }, { headerText: "Status", field: "FeeStatus" }, { headerText: "Department", field: "DepartmentDescription" }, { headerText: "Assessed Date", field: "AssessedDate", frozenEdge: "end" }, { headerText: "Payment Date", field: "PaymentDate" }, { headerText: "Paid By", field: "PaidBy", frozenEdge: "end" }, { headerText: "Invoice", field: "Invoice" }, { headerClassName: "table-header table-row-botton", className: "table-row-botton" }];

data.sort((a, b) => 
    a.field && b.field &&
    (order[a.frozenEdge] || order.default) - (order[b.frozenEdge] || order.default)
);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

1

This should work, if you want items with frozenEdge: "start" on top and frozenEdge: "end" on the bottom:

array.sort((x, y) => {
    if (y.frozenEdge === undefined && x.frozenEdge == undefined) return 0

    if (y.frozenEdge === undefined && x.frozenEdge == "end") return 1
    if (y.frozenEdge === undefined && x.frozenEdge == "start") return -1

    if (y.frozenEdge == "end" && x.frozenEdge == undefined) return -1
    if (y.frozenEdge == "start" && x.frozenEdge == undefined ) return 1
})

Checkout mdn docs on Array.prototype.sort() for more info.

It seems that in your "Expected Output" snippet you actually wanted to keep the first and last elements of the array at their indices before sorting. I'd suggest to pop() and shift() the last and first items respectively, something like this:

const first = array.shift()
const last = array.pop()

array = array.sort( /*...*/ )

array = [first, ...array, last]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.