Skip to content

Commit

Permalink
ecrmnn#291 implement sortByMany
Browse files Browse the repository at this point in the history
  • Loading branch information
shafi- committed May 6, 2023
1 parent eb37a5a commit 2bd7754
Show file tree
Hide file tree
Showing 8 changed files with 535 additions and 0 deletions.
143 changes: 143 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ All available methods
- [sort](#sort)
- [sortBy](#sortby)
- [sortByDesc](#sortbydesc)
- [sortByMany](#sortbymany)
- [sortDesc](#sortdesc)
- [sortKeys](#sortkeys)
- [sortKeysDesc](#sortkeysdesc)
Expand Down Expand Up @@ -2519,6 +2520,148 @@ sorted.all();

This method has the same signature as the `sortBy` method, but will sort the collection in the opposite order.

#### `sortByMany()`

The sortByMany method sorts the collection by the given key. The sorted collection keeps the original array keys, so in this example we'll use the values method to reset the keys to consecutively numbered indexes:

```js
const collection = collect([
{ name: 'Desk', price: 200 },
{ name: 'Chair', price: 100 },
{ name: 'Bookcase', price: 150 },
]);

const sorted = collection.sortByMany(['price']);

sorted.all();

// [
// { name: 'Chair', price: 100 },
// { name: 'Bookcase', price: 150 },
// { name: 'Desk', price: 200 },
// ]
```

You can use multiple keys to sort. Keys are considered in the order they appear in the parameter.

```js
const collection = collect([
{ name: 'Desk', price: 200 },
{ name: 'Table', price: 200 },
{ name: 'Chair', price: 100 },
{ name: 'Bookcase', price: 150 },
]);

const sorted = collection.sortByMany(['price', 'name']);

sorted.all();

// [
// { name: 'Chair', price: 100 },
// { name: 'Bookcase', price: 150 },
// { name: 'Desk', price: 200 },
// { name: 'Table', price: 200 },
// ]
```

You can use dot notation to sort by nested values
```js
const collection = collect([
{
name: 'Desk',
price: 200,
manufacturer: {
name: 'IKEA',
},
},
{
name: 'Chair',
price: 100,
manufacturer: {
name: 'Herman Miller',
},
},
{
name: 'Bookcase',
price: 150,
manufacturer: {
name: 'IKEA',
},
},
]);

const sorted = collection.sortByMany(['manufacturer.name']);

sorted.all();

// [
// {
// name: 'Chair',
// price: 100,
// manufacturer: {
// name: 'Herman Miller',
// },
// },
// {
// name: 'Desk',
// price: 200,
// manufacturer: {
// name: 'IKEA',
// },
// },
// {
// name: 'Bookcase',
// price: 150,
// manufacturer: {
// name: 'IKEA',
// },
// },
// ]
```

You can also pass your own callback to determine how to sort the collection values:

```js
const collection = collect([
{ name: 'Desk', colors: ['Black', 'Mahogany'] },
{ name: 'Chair', colors: ['Black'] },
{ name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
]);

const sorted = collection.sortByMany([(product, key) => product.colors.length]);

sorted.all();

// [
// { name: 'Chair', colors: ['Black'] },
// { name: 'Desk', colors: ['Black', 'Mahogany'] },
// { name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
// ]
```

You can also pass multiple callbacks of your own to determine how to sort the collection values:
```js
const collection = collect([
{ name: 'Desk', colors: ['Black', 'Mahogany'] },
{ name: 'Chair', colors: ['Black', 'Mahogany'] },
{ name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
]);

const sorted = collection.sortByMany([
(product, key) => product.colors.length,
(product, key) => product.name,
]);

sorted.all();

// [
// { name: 'Chair', colors: ['Black', 'Mahogany'] },
// { name: 'Desk', colors: ['Black', 'Mahogany'] },
// { name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
// ]
```


#### `sortDesc()`

This method will sort the collection in the opposite order as the `sort` method.
Expand Down
3 changes: 3 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ var SymbolIterator = require('./methods/symbol.iterator');
if (typeof Symbol !== 'undefined') {
Collection.prototype[Symbol.iterator] = SymbolIterator;
}


/**
* Support JSON.stringify
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
Expand Down Expand Up @@ -121,6 +123,7 @@ Collection.prototype.sort = require('./methods/sort');
Collection.prototype.sortDesc = require('./methods/sortDesc');
Collection.prototype.sortBy = require('./methods/sortBy');
Collection.prototype.sortByDesc = require('./methods/sortByDesc');
Collection.prototype.sortByMany = require('./methods/sortByMany');
Collection.prototype.sortKeys = require('./methods/sortKeys');
Collection.prototype.sortKeysDesc = require('./methods/sortKeysDesc');
Collection.prototype.splice = require('./methods/splice');
Expand Down
36 changes: 36 additions & 0 deletions dist/methods/sortByMany.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

var _require = require('../helpers/is'),
isFunction = _require.isFunction;
var nestedValue = require('../helpers/nestedValue');
var getValue = function getValue(item, valueOrFunction) {
if (isFunction(valueOrFunction)) {
return valueOrFunction(item);
}
return nestedValue(item, valueOrFunction);
};
module.exports = function sortByMany() {
var valuesOrFunctions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var collection = [].concat(this.items);
collection.sort(function (a, b) {
for (var index = 0; index < valuesOrFunctions.length; index += 1) {
var criteria = valuesOrFunctions[index];
var valueA = getValue(a, criteria);
var valueB = getValue(b, criteria);
if (valueA === null || valueA === undefined) {
return 1;
}
if (valueB === null || valueB === undefined) {
return -1;
}
if (valueA < valueB) {
return -1;
}
if (valueA > valueB) {
return 1;
}
}
return 0;
});
return new this.constructor(collection);
};
142 changes: 142 additions & 0 deletions docs/api/sortByMany.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# `sortByMany()`

The sortByMany method sorts the collection by the given key. The sorted collection keeps the original array keys, so in this example we'll use the values method to reset the keys to consecutively numbered indexes:

```js
const collection = collect([
{ name: 'Desk', price: 200 },
{ name: 'Chair', price: 100 },
{ name: 'Bookcase', price: 150 },
]);

const sorted = collection.sortByMany(['price']);

sorted.all();

// [
// { name: 'Chair', price: 100 },
// { name: 'Bookcase', price: 150 },
// { name: 'Desk', price: 200 },
// ]
```

You can use multiple keys to sort. Keys are considered in the order they appear in the parameter.

```js
const collection = collect([
{ name: 'Desk', price: 200 },
{ name: 'Table', price: 200 },
{ name: 'Chair', price: 100 },
{ name: 'Bookcase', price: 150 },
]);

const sorted = collection.sortByMany(['price', 'name']);

sorted.all();

// [
// { name: 'Chair', price: 100 },
// { name: 'Bookcase', price: 150 },
// { name: 'Desk', price: 200 },
// { name: 'Table', price: 200 },
// ]
```

You can use dot notation to sort by nested values
```js
const collection = collect([
{
name: 'Desk',
price: 200,
manufacturer: {
name: 'IKEA',
},
},
{
name: 'Chair',
price: 100,
manufacturer: {
name: 'Herman Miller',
},
},
{
name: 'Bookcase',
price: 150,
manufacturer: {
name: 'IKEA',
},
},
]);

const sorted = collection.sortByMany(['manufacturer.name']);

sorted.all();

// [
// {
// name: 'Chair',
// price: 100,
// manufacturer: {
// name: 'Herman Miller',
// },
// },
// {
// name: 'Desk',
// price: 200,
// manufacturer: {
// name: 'IKEA',
// },
// },
// {
// name: 'Bookcase',
// price: 150,
// manufacturer: {
// name: 'IKEA',
// },
// },
// ]
```

You can also pass your own callback to determine how to sort the collection values:

```js
const collection = collect([
{ name: 'Desk', colors: ['Black', 'Mahogany'] },
{ name: 'Chair', colors: ['Black'] },
{ name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
]);

const sorted = collection.sortByMany([(product, key) => product.colors.length]);

sorted.all();

// [
// { name: 'Chair', colors: ['Black'] },
// { name: 'Desk', colors: ['Black', 'Mahogany'] },
// { name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
// ]
```

You can also pass multiple callbacks of your own to determine how to sort the collection values:
```js
const collection = collect([
{ name: 'Desk', colors: ['Black', 'Mahogany'] },
{ name: 'Chair', colors: ['Black', 'Mahogany'] },
{ name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
]);

const sorted = collection.sortByMany([
(product, key) => product.colors.length,
(product, key) => product.name,
]);

sorted.all();

// [
// { name: 'Chair', colors: ['Black', 'Mahogany'] },
// { name: 'Desk', colors: ['Black', 'Mahogany'] },
// { name: 'Bookcase', colors: ['Red', 'Beige', 'Brown'] },
// ]
```

[View source on GitHub](https://github.com/ecrmnn/collect.js/blob/master/src/methods/sortByMany.js)
12 changes: 12 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,18 @@ declare module 'collect.js' {
*/
sortByDesc(fn: (item: Item) => number): Collection<Item>;

/**
* The sortByMany method sorts the collection by the given keys.
* The sorted collection keeps the original array keys.
*/
sortByMany<V>(keys: V): Collection<Item>;

/**
* The sortByMany method sorts the collection by the given callbacks.
* The sorted collection keeps the original array keys.
*/
sortByMany(fns: ((item: Item) => number)[]): Collection<Item>;

/**
* The splice method removes and returns a slice of items starting at the specified index.
* You may pass a second argument to limit the size of the resulting chunk.
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ Collection.prototype.sort = require('./methods/sort');
Collection.prototype.sortDesc = require('./methods/sortDesc');
Collection.prototype.sortBy = require('./methods/sortBy');
Collection.prototype.sortByDesc = require('./methods/sortByDesc');
Collection.prototype.sortByMany = require('./methods/sortByMany');
Collection.prototype.sortKeys = require('./methods/sortKeys');
Collection.prototype.sortKeysDesc = require('./methods/sortKeysDesc');
Collection.prototype.splice = require('./methods/splice');
Expand Down
Loading

0 comments on commit 2bd7754

Please sign in to comment.