0

I have JSON which Each records attributes has seperate object, I want to sort by attributes dynamically.

I am manage to do dthe sorting with attributes, but it's static code. How Could I make it dynamically ?

Please find running code on : https://jsfiddle.net/b8fv4L1z/3/

var json = [
  [
    {
      "apiName": "Name",
      "value": "Bob"
      },
    {
      "apiName": "CompanyName",
      "value": "Google"
    }
  ],
  [
    {
      "apiName": "Name",
      "value": "Micky"
    },
    {
      "apiName": "CompanyName",
      "value": "Amazon"
    }
  ],
  [
    {
      "apiName": "Name",
      "value": "Donal"
    },
    {
      "apiName": "CompanyName",
      "value": "Facebook"
    }
  ]
];


 function Comparator(a, b, ) {

   if (a[1].value < b[1].value) return -1; // a[1] sort by CompanyName If I put a[0] it will sort by Name.
   if (a[1].value > b[1].value) return 1; // a[1] sort by CompanyName If I put a[0] it will sort by Name.
   return 0;
 }

json = json.sort(Comparator);
console.log(JSON.stringify(json));


Expected Result:

(Sorted by apiName = CompanyName):

 [[{"apiName":"Name","value":"Micky"},{"apiName":"CompanyName","value":"Amazon"}],[{"apiName":"Name","value":"Donal"},{"apiName":"CompanyName","value":"Facebook"}],[{"apiName":"Name","value":"Bob"},{"apiName":"CompanyName","value":"Google"}]]

(Sorted by apiName = Name):

     [[{"apiName":"Name","value":"Bob"},{"apiName":"CompanyName","value":"Google"}],[{"apiName":"Name","value":"Donal"},{"apiName":"CompanyName","value":"Facebook"}],[{"apiName":"Name","value":"Micky"},{"apiName":"CompanyName","value":"Amazon"}]]
2
  • 1
    please add the wanted result as well. what is the rule for sorting by name? you have nested arrays. on which array shoulf the sorting happen? Commented Apr 17, 2019 at 11:07
  • As, I have update. Expected result should be short by attributs. I can manage to do the sort by static value. I want to make it dynamic. Currently I have two attributes (Name & CompanyName) in future I have multiple attributs. How I can make it dynamically. Commented Apr 17, 2019 at 11:14

2 Answers 2

3

With comparator made higher-order function.

var json = [
  [{
      "apiName": "Name",
      "value": "Bob"
    },
    {
      "apiName": "CompanyName",
      "value": "Google"
    }
  ],
  [{
      "apiName": "Name",
      "value": "Micky"
    },
    {
      "apiName": "CompanyName",
      "value": "Amazon"
    }
  ],
  [{
      "apiName": "Name",
      "value": "Donal"
    },
    {
      "apiName": "CompanyName",
      "value": "Facebook"
    }
  ]
];

function findValueByProperty(item, propertyName) {
  var relevantRow = item.find(function(content) {
    return content.apiName === propertyName;
  });
  return relevantRow.value;
}

function comparator(propertyName) {
  return function(a, b) {
    var valueA = findValueByProperty(a, propertyName);
    var valueB = findValueByProperty(b, propertyName);
    return valueA.localeCompare(valueB)
  }
}

console.log('json==>' + JSON.stringify(json));
console.log(json.slice().sort(comparator("CompanyName")));
console.log(json.slice().sort(comparator("Name")));

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

3 Comments

Thank you for sharing, I get only propertt name. How I can find the index for the same ? e.g: sort by Name or CompanyName or somet other value (which index not be deceded)
Edited to execute lookup property name.
Both my original answer and Piyush's comment predate your answer.
2

You could find the wanted property. Maybe you need a default value, like an empty string.

function sort(array, apiName) {
    const
        getValue = array => 
            (array.find(o => o.apiName === apiName) || { value: '' }).value;

    return array.sort((a, b) => getValue(a).localeCompare(getValue(b)));
}

var array = [[{ apiName: "Name", value: "Bob" }, { apiName: "CompanyName", value: "Google" }], [{ apiName: "Name", value: "Micky" }, { apiName: "CompanyName", value: "Amazon" }], [{ apiName: "Name", value: "Donal" }, { apiName: "CompanyName", value: "Facebook" }]];

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

If you have always the same data structure, you could get the apiName in advance and sort without a finding for every element.

function sort(array, apiName) {
    const index = array[0].findIndex(o => o.apiName === apiName);

    return array.sort((a, b) => a[index].value.localeCompare(b[index].value));
}

var array = [[{ apiName: "Name", value: "Bob" }, { apiName: "CompanyName", value: "Google" }], [{ apiName: "Name", value: "Micky" }, { apiName: "CompanyName", value: "Amazon" }], [{ apiName: "Name", value: "Donal" }, { apiName: "CompanyName", value: "Facebook" }]];

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

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.