1

I have an array as follows:

var arr1 = [{x: 0, y: 0}, {x: 10, y: 10}, {x: 20, y: 20}, {x: 30, y: 30}, {x: 40, y: 40}]

arr1 represents the data in an infotable created by a user and I have sorted arr1 in ascending order of x using .sort.

arr1.sort(function(a, b){return a.x - b.x});

When the user changes the name of the values in the infotable (arr1) from x to z or creates a new infotable with different names, I have to modify my code to sort it again.

var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}]

arr1.sort(function(a, b){return a.z - b.z});

Therefore, I want my sort function to be dynamic so that I do not have to change the code when the name of the values in the array is changed or when an infotable with new names is created. I hope I got my question across clearly, any help is greatly appreciated!

3
  • If the name of the property changes, how would the algorithm know which property to sort by? You can use the function Object.getOwnPropertyNames(obj) to find all properties on an object, but you would need to somehow determine which one to sort by. Always the first one perhaps? Commented Nov 22, 2019 at 2:02
  • Dynamic means when an Asynchronous activity occurs, such as an Event. You still have to already have written the code to execute. It's not magic. Commented Nov 22, 2019 at 3:09
  • I am actually drawing a chart on the Thingworx IoT platform and the array represents the x and y coordinates of the data points, so the array should be sorted according to the user's input in the composer. For example, he can select a value (x, y or z) from a drop-down list and this selection will determine which property to sort by. Commented Nov 22, 2019 at 3:39

7 Answers 7

2

You could store the key to sort by in a variable and use that variable instead. Example:

var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}]

let keyToSortBy = 'z'
arr1.sort(function(a, b){return a[keyToSortBy] - b[keyToSortBy]});
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I realized I was using arr1.sort(function(a, b){return a.keyToSortBy - b.keyToSortBy}); instead of your solution.
1

If you are a fan of lodash.

import _ from "lodash"
let key = 'z' // dynamic key
_.sortBy(arr1, key);

Comments

0

You need to figure out a way to dynamically tell your algorithm what's the field you need to sort by. One example would be including a property in each element with the name of the field to sort. Sample:

var arr1 = [{x: 0, y: 0, sort: 'x'}, {x: 10, y: 10, sort: 'x'}]
var arr1 = [{z: 0, y: 0, sort: 'z'}, {z: 10, y: 10, sort: 'z'}]

Then, your sort function would be the same:

var sortFunction = function(a, b){return a[a['sort']] - b[b['sort']]}

arr1.sort(sortFunction);
arr2.sort(sortFunction);

Comments

0

Your sample data doesn't show much difference with the value sorted by either key as the results are the same for either sort.

I changed your data slightly to show the differences using the FF console.log

The sort function could be condensed by calling a function instead of the inline defined logic.

` Test Page

</style>
</head><body>

<script>
console.clear();

var arr1 = [{z: 0, y: 40}, {z: 10, y: 30}, {z: 20, y: 20}, {z: 30, y: 10}, {z: 40, y: 0}];
console.log('original');
console.log(arr1.toSource());
console.log();

let keyToSortBy = 'z'
arr1.sort(function(a, b){return a[keyToSortBy] - b[keyToSortBy]});
console.log('original sorted by ascending "z"');
console.log(arr1.toSource());
console.log();

keyToSortBy = 'y'
arr1.sort(function(a, b){return a[keyToSortBy] - b[keyToSortBy]});
console.log('original sorted by ascending "y"');
console.log(arr1.toSource());
console.log();

</script>

</body></html>

`

Comments

0

Make a function that returns a function:

var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}]
    
const sortBy = (key) => (a, b) => a[key] - b[key];
    
arr1.sort(sortBy('z'));
    
console.log(arr1);

If you need, you may "encode" the key in the array as a property (not iteratable):

var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}];
arr1.sortKey = 'z';
    
const sortBy = (key) => (a, b) => a[key] - b[key];
    
arr1.sort(sortBy(arr1.sortKey));
    
console.log(arr1);

And last, you may create your own sort function to ALL arrays in your program:

var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}];
arr1.sortKey = 'z';
    
Array.prototype.mySort = function() {
    this.sort((a, b) => a[this.sortKey] - b[this.sortKey]);
};

arr1.mySort();

    
console.log(arr1);

Comments

0

You can add a sortByKey to the Array prototype:

Array.prototype.sortByKey = function (key) {
  return this.sort((a, b) => a[key] - b[key]);
};

const arr = [
  { x: 1, y: 100 },
  { x: 100, y: 5 },
  {x: 3, y: 99 },
];

console.log(arr.sortByKey('x'));
console.log(arr.sortByKey('y'));

Comments

0

See the example below. Every time you make a change use xzSort.

function xzSort(array){
  array.sort(function(a, b){
    var A = 'x' in a ? 'x' : 'z';
    var B = 'x' in b ? 'x' : 'z';
    return a[A] - b[B];
  });
  return array;
}
var a = [{z:40, y:40}, {z:10, y:10}, {z:0, y:0}, {z:20, y:20}, {z:30, y:30}];
console.log(a); console.log(xzSort(a)); a[3] = {x:10, y:15}; console.log(xzSort(a));

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.