Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#291 implement sortByMany #320

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 147 additions & 1 deletion 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 @@ -2515,10 +2516,155 @@ sorted.all();
// ]
```

You can also pass array of criteria or callbacks to determine how to sort the collection values:

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

const sorted = collection.sortBy(['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.sortBy(['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.sortBy(['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.sortBy([(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.sortBy([
(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'] },
// ]
```


#### `sortByDesc()`

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:


#### `sortDesc()`

This method will sort the collection in the opposite order as the `sort` method.
Expand Down Expand Up @@ -3357,4 +3503,4 @@ PRs are welcomed to this project, and help is needed in order to keep up with th

### License

MIT © [Daniel Eckermann](https://danieleckermann.com)
MIT © [Daniel Eckermann](https://danieleckermann.com)
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);
};
141 changes: 140 additions & 1 deletion docs/api/sortBy.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,143 @@ sorted.all();
// ]
```

[View source on GitHub](https://github.com/ecrmnn/collect.js/blob/master/src/methods/sortBy.js)
You can also pass array of criteria or callbacks to determine how to sort the collection values:

```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/sortBy.js)
Loading