How to clean empty array objects and renumber them? - javascript

I have a JavaScript object like
{0: [], 1: [0: 'a', 1: 'b'], 2: [], 3: [0: '20']}
I want to get rid of the empty slots in this object and renumber the remaining one, so it has a normal order (0, 1, 2).
I use this function:
function clean(obj) {
for (var propName in obj) {
if (obj[propName] === null || obj[propName].length == 0 || obj[propName] === undefined) {
delete obj[propName];
}
}
}
Which clears the object, but then I get
{1: [0: 'a', 1: 'b'], 3: [0: '20']}
But how do I make 1 to 0 and 3 to 1?

First of all, there's a problem with your question since the definition of your first object does not pass JS compilation. The array elements are given a "key" with the index, you wrote... 1: [0: 'a', 1: 'b'] which should be either:
1: {0: 'a', 1: 'b'}
or
1: ['a','b']
You are obviously mixing up between the index of an array, and the keys of an object.
Here you are giving the object keys the name of their index within their array. So perhaps you are asking one of three questions. (I'll answer each):
// 1. Clean [[], ['a','b'], [], '20']
// returning: [['a','b'], ['20']]
// and not using params at all.
// 2. Clean {0: [], 1: ['a','b'], 2: [], 3: ['20']}
// returning: {0: ['a','b'], 1: ['20']}
// 3. Clean {0: {}, 1: {0: 'a', 1: 'b'}, 2: {}, 3: {0: '20'}}
// returning: {0: {0: 'a', 1:'b'}, 1: {0: '20'}}
The fastest way, keeping your function intact, would be to add a new "indexer" at the bottom of your function, correcting the keys. We can use ES6 as follows:
// if to delete...
let oldKey = paramName;
let newKey = (obj.keys().indexOf(oldKey)) - 1;
delete obj[oldKey].assign(o, {[newKey]: o[oldKey] })[oldKey];
This is not very clear.
The clearest way is to use another object and populate the next element only if the original has a value, starting with index zero and increasing it.
function cleanup(obj) {
let newObj = {};
let idx = 0;
for (var propName in obj) {
let prop = obj[propName];
console.log('prop', propName, JSON.stringify(prop))
if (prop !== null
&& prop !== undefined
&& JSON.stringify(prop) != "[]" // not empty array
&& JSON.stringify(prop) !== "{}") { // not empty obj
newObj[idx] = prop;
idx++;
}
}
return newObj;
}
See my JS fiddle which shows this.
You could also use the object's keys() method to get an array of the keynames in the order you would get them from the iterator. For the array you could use the splice(0,idx) to remove that element out.
https://www.w3schools.com/js/js_array_methods.asp
Or you can use the split, but then you have to work "backwards", otherwise the for loop will not work correctly. So first get the propnames, and then work from the last one to the first popping as you go along.

I recommend using an Array instead of an Object, but you could do something like this:
var obj = {0: [], 1: ['a', 'b'], 2: [], 3: ['20']};
var newObj = Object.keys(obj).reduce(function (acc, k) {
var objVal = obj[k];
if (objVal.length) {
acc[Object.keys(acc).length] = objVal;
}
return acc;
}, {});
console.log(newObj);

Assuming arrays as properties, you could filter by length (with a destructuring assignment) and assign this array to an object.
var data = { 0: [], 1: ['a', 'b'], 2: [], 3: ['20'] },
clean = Object.assign({}, Object.values(data).filter(({ length }) => length));
console.log(clean);

Assuming that the index value is implicit
const data = {
0: [],
1: ['a', 'b'],
2: [],
3: ['20']
}
const newData = {};
for (const property in data) {
if (data[property].length !== 0) {
newData[property] = data[property]
}
}
console.log(newData)

This is my suggestion. Also do not use index in array declarations: [0: 'a', 1: 'b'] should be ['a', 'b'].
const data = {0: [], 1: ['a', 'b'], 2: [], 3: ['20']};
const dataArray = Object.values(data);
let result = {};
let index = 0;
dataArray.forEach(d => {
if (d.length) Object.assign(result, {[index++]: d});
})
// result --> {0: ['a', b'], 1: ['20']}

Related

Create Double Array from equal elements

I am new at Javascript. I want to create of 2D array from equal elements (elements are objects). For instance,
oldArray = [a,b,c,d,e,f] (a=b=f, d=e)
Lets say object a is equal to object b and object f. Then object d is equal to object e. So the new Array should be
newArray = [[a,b,f],[c],[d,e]]
Any help would be appreciated.
Create a groupBy function using Array.reduce(). The groupBy function accepts a predicate, so you can define the grouping property/value. The result of the grouping is an object where each property is a group of items (array). Use Object.values() to extract to an array of arrays.
const groupBy = (predicate, arr) =>
arr.reduce((r, o) => ({
...r,
[predicate(o)]: [...r[predicate(o)] || [], o]
}), {});
const data = [{ id: 'a', val: 1 }, { id: 'b', val: 1 }, { id: 'c', val: 2 }, { id: 'd', val: 3 }, { id: 'e', val: 3 }, { id: 'f', val: 1 }];
const result = Object.values(groupBy(({ val}) => val, data));
console.log(result);
You can try following
Create a temp array which contains objects with properties
obj - reference of the object
index - index of object in the resulting array
Iterate over the oldArray and for each object in it check whether it exists in temp array.
If it does not exist, add an entry for it in temp array and also add it to the result array.
Else update the existing sub-array in result array.
let a = {x:1}, c = {y:2}, d = {z:3};
let b = a, f = a, e = d;
let oldArray = [a,b,c,d,e,f];
let result = [];
let temp = [];
oldArray.forEach(c => {
let item = temp.find(o => o.obj === c);
if(item) result[item.index].push(c);
else {
temp.push({obj:c,index:result.length});
result.push([c]);
}
});
console.log(result);

Given 2 objects, create a third object containing both value from object 1 and 2 and KEEP original order

it should be quick and simple but NOT :(
I have 2 array of objects which looks like this:
var obj1 = {
1: "Available"
3: "Available - Sleeps"
}
var obj2 = {
2: "Not Available"
4: "Holidays"
6: "Sick"
}
I would like to have a 3rd object whihc is the merge of the 2 mantaining the original order, like this:
var obj3 = {
1: "Available"
3: "Available - Sleeps"
2: "Not Available"
4: "Holidays"
6: "Sick"
}
Unfortunately it always order the items by key so I get this :( :
var obj3 = {
1: "Available"
2: "Not Available"
3: "Available - Sleeps"
4: "Holidays"
6: "Sick"
}
I have tried different ways to merge the object but the order never stays the same, I have tried:
$.extend(obj3, obj1, obj2);
obj3 = Object.assign(obj1, obj2);
obj3 = {...obj1,...obj2}
Any ideas anyone :)
Thanks
You cannot create an object whose properties will be enumerated in the order you've said you want with those property keys. As of ES2015, object properties do have an order (officially specified only for some operations, but all modern JavaScript engines also apply it to the unspecified operations). One aspect of that order is that properties whose names are integer indexes as defined by the spec* are visited in numeric order. Your 1, 2, 3, etc. properties fit the definition of integer index keys, and so the combined object's properties will be enumerated in 1, 2, 3, ... order.
Instead, use an array:
const obj3 = [];
Object.keys(obj1).forEach(key => { obj3.push({key, value: obj1[key]}); });
Object.keys(obj2).forEach(key => { obj3.push({key, value: obj2[key]}); });
var obj1 = {
1: "Available",
3: "Available - Sleeps"
};
var obj2 = {
2: "Not Available",
4: "Holidays",
6: "Sick"
};
const obj3 = [];
Object.keys(obj1).forEach(key => { obj3.push({key, value: obj1[key]}); });
Object.keys(obj2).forEach(key => { obj3.push({key, value: obj2[key]}); });
console.log(obj3);
.as-console-wrapper {
max-height: 100% !important;
}
...although technically, if you made those names not integer indexes, you could create an object with properties that would be numerated in that order:
var obj3 = {};
Object.keys(obj1).forEach(key => { obj3["x" + key] = obj1[key]; });
Object.keys(obj2).forEach(key => { obj3["x" + key] = obj2[key]; });
var obj1 = {
1: "Available",
3: "Available - Sleeps"
};
var obj2 = {
2: "Not Available",
4: "Holidays",
6: "Sick"
};
var obj3 = {};
Object.keys(obj1).forEach(key => { obj3["x" + key] = obj1[key]; });
Object.keys(obj2).forEach(key => { obj3["x" + key] = obj2[key]; });
console.log(obj3);
But I don't recommend it.
* Defined here:
An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1.
Maybe This is helpful.
var obj1 = {
1: "Available",
3: "Available - Sleeps"
}
var obj2 = {
2: "Not Available",
4: "Holidays",
6: "Sick"
}
const merged = Object.values(obj1).concat(Object.values(obj2)).reduce((result, value, index)=>{result[index] = value; return result},{})
console.log(merged)
Object property enumeration order isn't reliable.
Use Map instead since it preserves insertion order:
const map1 = new Map([
[1, "Available"],
[3, "Available - Sleeps"]
])
const map2 = new Map([
[2, "Not Available"],
[4, "Holidays"],
[6, "Sick"]
])
const map3 = new Map([...map1, ...map2])
console.log([...map3])
// Also you can easily convert and object to dictionary:
const fromPairs = pairs => {
const obj = {}
for (let [key, value] of pairs)
obj[key] = value
return obj
}
const obj = fromPairs(map3)
console.log(obj)
See this other Q&A to get more insights about object property enumeration order: Does JavaScript Guarantee Object Property Order?
If you really want to keep the order of the keys, here is what I would do if I were you:
var obj1 = {
1: "Available",
3: "Available - Sleeps"
};
var obj2 = {
2: "Not Available",
4: "Holidays",
6: "Sick"
}
Object.defineProperty(Object.prototype, 'orderedKeys', {
get: function () {
return this.hasOwnProperty('orderedKeys') ? this.orderedKeys : Object.keys(this);
},
enumerable: false
});
Object.defineProperty(Object.prototype, 'concat', {
value: function (obj) {
return {
...this,
...obj,
orderedKeys: this.orderedKeys.concat(Object.keys(obj))
};
},
enumerable: false
});
var obj3 = obj1.concat(obj2);
console.log(obj3);
for(const key of obj3.orderedKeys) {
console.log(key, obj3[key]);
}
This way, you can always keep an ordered version of your keys in orderedKeys so that you can use it later.

es6 merge two array of objects and override the existing object

I have 2 array of objects:
const arr1 = [{'id':'1' 'value':'yes'}, {'id':'2', 'value':'no'}];
const arr2 = [{'id':'2', 'value':'yes'}];
So, if I try and merge these 2 arrays the result should be:
arrTemp = [{'id':'1', 'value':'yes'}, {'id':'2', 'value':'yes'}];
Basically, it should work similar to Object.assign(), but no matter what I try it does not work. Could anyone please help me in this ?
I modified the data structure. Is it possible to merge them now and get the output.
Thanks
This is how you can get the job done with ES6 spread, reduce and Object.values.
const arr1 = [{
'id': '1',
'value': 'yes'
}, {
'id': '2',
'value': 'no'
}];
const arr2 = [{
'id': '2',
'value': 'yes'
}];
const result = Object.values([...arr1, ...arr2].reduce((result, {
id,
...rest
}) => {
result[id] = {
...(result[id] || {}),
id,
...rest
};
return result;
}, {}));
console.log(result);
const result = Object.entries(Object.assign({}, ...arr1,...arr2)).map(([key, value]) => ({[key]:value}));
You could spread (...) the arrays into one resulting object ( via Object.assign) and then map its entries to an array again.
You could work with a valid ES6 data structure like a map for example:
const 1 = { 1: { string: 'yes' }, 2: { string: 'no' } }
const 2 = { 2: { string: 'yes' }, 3: { string: 'no' } }
const 3 = { ...1, ...2}
This will override your first argument with the second one or just combine them where possible.
Just try it out in your browser it's a lot easier and enhances performance since you will never have to use findById() which is an expensive operation.
In javascript, arrays are simply objects indexed by numbers starting from 0.
So when you use Object.assign on arr1 and arr2 you will override the first item in the arr1 with the first item in arr2 because they are both indexed under the key 0.
your result will be:
[
{ '2': 'yes' },
{ '2': 'no' }
]
(or in object syntax:)
{
0: { '2': 'yes' },
1: { '2': 'no' }
}
Instead of using arrays, you could create an object indexed by the number string (which is how you seem to be thinking of the array in any case).
So you could change your original data structure to make the job easier:
const arr1 = {
'1': 'yes',
'2': 'no'
};
const arr2 = {
'2': 'yes'
};
const result = Object.assign(arr1, arr2);
You could take a Map as reference to the new assigned object in the result array and build first a new array with a copy of the objects and then iterate the second array and update the objects with the same key.
var array1 = [{ 1: 'yes' }, { 2: 'no' }],
array2 = [{ 2: 'yes' }],
getKey = o => Object.keys(o)[0],
map = new Map,
result = array1.map(o => (k => map.set(k, Object.assign({}, o)).get(k))(getKey(o)));
array2.forEach(o => Object.assign(map.get(getKey(o)), o));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Array reduce could come in handy is this case. See example below:
[...arr1, ...arr2].reduce((acc, item) => {
const updated = acc.find(a => a.id === item.id)
if (!updated) {
acc.push(item)
} else {
const index = acc.indexOf(updated)
acc[index] = { ...item, ...acc[index] }
}
return acc
}, [])
simple way to add with exist array of object:
const arr1 = [{ "name":"John", "age":30, "car":"toyata" }];
const arr2 = [{ "name":"Ales", "age":40, "car":"Nissan" }];
Array.prototype.push.apply(arr1, arr2);
Result:=>
console.log(arr1)
For anyone finding this answer at a later point in time. There are a couple of ways that you could want this to work exactly, but you could filter all adjusted elements in the first array, and then combine it with the second array.
const arr3 = [...arr1.filter(item1 => !arr2.find(item2 => item1.id === item2.id)), ...arr2]
Alternatively, you could update the elements in the first array, and then filter them from the second array instead.
You cannot use array.prototype map because the key of arr1 and arr2 have the same value '2'.
You should use something like this
for (var i = 0, l = arr1.length; i < l; i++) {
var key = Object.keys(arr1[i]);
if (!arr2[key]) { arr2[key] = []; }
arr2[key].push(arr1[i][key]);
}
Regards

How do I merge an array of objects in Javascript?

Example:
var array1 = [ {'key':1, 'property1': 'x'}, {'key':2, 'property1': 'y'} ]
var array2 = [ {'key':2, 'property2': 'a'}, {'key':1, 'property2': 'b'} ]
I want merge(array1, array2) to give me:
[
{'key':1, 'property1': 'x', 'property2' : 'b'},
{'key':2, 'property1': 'y', 'property2' : 'a'}
]
Is there an easy way to do this?
EDIT: several people have answered without looking too closely at my problem, please be note that I want to match similar objects in each array and combine their properties into my final array. Keys are unique and there will only ever be at most one object with a particular key in each array.
I wrote a quick not-so-quick solution. The one problem you might want to consider is whether a property from an object in the second array should override the same property, if present, in the second object it's being compared to.
Solution 1
This solution is of complexity O(n²). Solution 2 is much faster; this solution is only for those who don't want to be Sanic the Hedgehog fast.
JavaScript
var mergeByKey = function (arr1, arr2, key) {
// key is the key that the function merges based on
arr1.forEach(function (d, i) {
var prop = d[key];
// since keys are unique, compare based on this key's value
arr2.forEach(function (f) {
if (prop == f[key]) { // if true, the objects share keys
for (var x in f) { // loop through each key in the 2nd object
if (!(x in d)) // if the key is not in the 1st object
arr1[i][x] = f[x]; // add it to the first object
// this is the part you might want to change for matching properties
// which object overrides the other?
}
}
})
})
return arr1;
}
Test Case
var arr = [ {'key':1, 'property1': 'x'},
{'key':2, 'property1': 'y'} ],
arr2= [ {'key':2, 'property2': 'a'},
{'key':1, 'property2': 'b'} ];
console.log(mergeByKey(arr, arr2, "key"));
Results
/* returns:
Object
key: 1
property1: "x"
property2: "b"
__proto__: Object
and
Object
key: 2
property1: "y"
property2: "a"
__proto__: Object
*/
fiddle
Solution 2
As Vivin Paliath pointed out in the comments below, my first solution was of O(n²) complexity (read: bad). His answer is very good and provides a solution with a complexity of O(m + n), where m is the size of the first array and n of the second array. In other words, of complexity O(2n).
However, his solution does not address objects within objects. To solve this, I used recursion—read: the devil, just like O(n²).
JavaScript
var mergeByKey = function (arr1, arr2, key) {
var holder = [],
storedKeys = {},
i = 0; j = 0; l1 = arr1.length, l2 = arr2.length;
var merge = function (obj, ref) {
for (var x in obj) {
if (!(x in ref || x instanceof Object)) {
ref[x] = obj[x];
} else {
merge(obj[x], ref[x]);
}
}
storedKeys[obj.key] = ref;
}
for (; i < l1; i++) {
merge(arr1[i], storedKeys[arr1[i].key] || {});
}
for (; j < l2; j++) {
merge(arr2[j], storedKeys[arr2[j].key] || {});
}
delete storedKeys[undefined];
for (var obj in storedKeys)
holder.push(storedKeys[obj]);
return holder;
}
Test Case
var arr1 = [
{
"key" : 1,
"prop1" : "x",
"test" : {
"one": 1,
"test2": {
"maybe" : false,
"test3": { "nothing" : true }
}
}
},
{
"key" : 2,
"prop1": "y",
"test" : { "one": 1 }
}],
arr2 = [
{
"key" : 1,
"prop2" : "y",
"test" : { "two" : 2 }
},
{
"key" : 2,
"prop2" : "z",
"test" : { "two": 2 }
}];
console.log(mergeByKey(arr1, arr2, "key"));
Results
/*
Object
key: 1
prop1: "x"
prop2: "y"
test: Object
one: 1
test2: Object
maybe: false
test3: Object
nothing: true
__proto__: Object
__proto__: Object
two: 2
__proto__: Object
__proto__: Object
Object
key: 2
prop1: "y"
prop2: "z"
test: Object
one: 1
two: 2
__proto__: Object
__proto__: Object
*/
This correctly merges the objects, along with all child objects. This solutions assumes that objects with matching keys have the same hierarchies. It also does not handle the merging of two arrays.
fiddle
You could do something like this:
function merge(array1, array2) {
var keyedResult = {};
function _merge(element) {
if(!keyedResult[element.key]) {
keyedResult[element.key] = {};
}
var entry = keyedResult[element.key];
for(var property in element) if(element.hasOwnProperty(property)) {
if(property !== "key") {
entry[property] = element[property];
}
}
entry["key"] = element.key;
}
array1.forEach(_merge);
array2.forEach(_merge);
var result = [];
for(var key in keyedResult) if(keyedResult.hasOwnProperty(key)) {
result.push(keyedResult[key]);
}
return result.sort(function(a, b) {
return a.key - b.key;
});
}
You could eliminate the sort if you don't care about the order. Another option is to use an array instead of the map I have used (keyedResult) if you have numeric keys and don't care about the array being sparse (i.e., if the keys are non-consecutive numbers). Here the key would also be the index of the array.
This solution also runs in O(n).
fiddle
It would be preferable to use existing infrastructure such as Underscore's _.groupBy and _.extend to handle cases like this, rather than re-inventing the wheel.
function merge(array1, array2) {
// merge the arrays
// [ {'key':1, 'property1': 'x'}, {'key':2, 'property1': 'y'}, {'key':2, 'property2': 'a'}, {'key':1, 'property2': 'b'} ]
var merged_array = array1.concat(array2);
// Use _.groupBy to create an object indexed by key of relevant array entries
// {1: [{ }, { }], 2: [{ }, { }]}
var keyed_objects = _.groupBy(merged_array, 'key');
// for each entry in keyed_objects, merge objects
return Object.keys(keyed_objects).map(function(key) {
return _.extend.apply({}, keyed_objects[key]);
});
}
The idea here is using _.extend.apply to pass the array of objects grouped under a particular key as arguments to _.extend, which will merge them all into a single object.

How can I use lodash/underscore to sort by multiple nested fields?

I want to do something like this:
var data = [
{
sortData: {a: 'a', b: 2}
},
{
sortData: {a: 'a', b: 1}
},
{
sortData: {a: 'b', b: 5}
},
{
sortData: {a: 'a', b: 3}
}
];
data = _.sortBy(data, ["sortData.a", "sortData.b"]);
_.map(data, function(element) {console.log(element.sortData.a + " " + element.sortData.b);});
And have it output this:
"a 1"
"a 2"
"a 3"
"b 5"
Unfortunately, this doesn't work and the array remains sorted in its original form. This would work if the fields weren't nested inside the sortData. How can I use lodash/underscore to sort an array of objects by more than one nested field?
I've turned this into a lodash feature request: https://github.com/lodash/lodash/issues/581
Update: See the comments below, this is not a good solution in most cases.
Someone kindly answered in the issue I created. Here's his answer, inlined:
_.sortBy(data, function(item) {
return [item.sortData.a, item.sortData.b];
});
I didn't realize that you're allowed to return an array from that function. The documentation doesn't mention that.
If you need to specify the sort direction, you can use _.orderBy with the array of functions syntax from Lodash 4.x:
_.orderBy(data, [
function (item) { return item.sortData.a; },
function (item) { return item.sortData.b; }
], ["asc", "desc"]);
This will sort first ascending by property a, and for objects that have the same value for property a, will sort them descending by property b.
It works as expected when the a and b properties have different types.
Here is a jsbin example using this syntax.
There is a _.sortByAll method in lodash version 3:
https://github.com/lodash/lodash/blob/3.10.1/doc/README.md#_sortbyallcollection-iteratees
Lodash version 4, it has been unified:
https://lodash.com/docs#sortBy
Other option would be to sort values yourself:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
function compareValues(v1, v2) {
return (v1 > v2)
? 1
: (v1 < v2 ? -1 : 0);
};
var data = [
{ a: 2, b: 1 },
{ a: 2, b: 2 },
{ a: 1, b: 3 }
];
data.sort(function (x, y) {
var result = compareValues(x.a, y.a);
return result === 0
? compareValues(x.b, y.b)
: result;
});
// data after sort:
// [
// { a: 1, b: 3 },
// { a: 2, b: 1 },
// { a: 2, b: 2 }
// ];
The awesome, simple way is:
_.sortBy(data, [function(item) {
return item.sortData.a;
}, function(item) {
return item.sortData.b;
}]);
I found it from check the source code of lodash, it always check the function one by one.
Hope that help.
With ES6 easy syntax and lodash
sortBy(item.sortData, (item) => (-item.a), (item) => (-item.b))
I think this could work in most cases with underscore:
var properties = ["sortData.a", "sortData.b"];
data = _.sortBy(data, function (d) {
var predicate = '';
for (var i = 0; i < properties.length; i++)
{
predicate += (i == properties.length - 1
? 'd.' + properties[i]
: 'd.' + properties[i] + ' + ')
}
return eval(predicate)
});
It works and you can see it in Plunker
If the problem is an integer is converted to a string, add zeroes before the integer to make it have the same length as the longest in the collection:
var maxLength = _.reduce(data, function(result, item) {
var bString = _.toString(item.sortData.b);
return result > bString.length ? result : bString.length;
}, 0);
_.sortBy(data, function(item) {
var bString = _.toString(item.sortData.b);
if(maxLength > bString.length) {
bString = [new Array(maxLength - bString.length + 1).join('0'), bString].join('');
}
return [item.sortData.a, bString];
});
I've found a good way to sort array by multiple nested fields.
const array = [
{id: '1', name: 'test', properties: { prop1: 'prop', prop2: 'prop'}},
{id: '2', name: 'test2', properties: { prop1: 'prop second', prop2: 'prop second'}}
]
I suggest to use 'sorters' object which will describe a key and sort order. It's comfortable to use it with some data table.
const sorters = {
'id': 'asc',
'properties_prop1': 'desc',//I'm describing nested fields with '_' symbol
}
dataSorted = orderBy(array, Object.keys(sorters).map(sorter => {
return (row) => {
if (sorter.includes('_')) { //checking for nested field
const value = row["properties"][sorter.split('_')[1]];
return value || null;
};
return row[sorter] || null;// checking for empty values
};
}), Object.values(sorters));
This function will sort an array with multiple nested fields, for the first arguments it takes an array to modify, seconds one it's actually an array of functions, each function have argument that actually an object from 'array' and return a value or null for sorting. Last argument of this function is 'sorting orders', each 'order' links with functions array by index. How the function looks like simple example after mapping:
orderBy(array, [(row) => row[key] || null, (row) => row[key] || null , (row) => row[key] || null] , ['asc', 'desc', 'asc'])
P.S. This code can be improved, but I would like to keep it like this for better understanding.

Categories