# query-methods

> SQL-like query methods for arrays in JavaScript

Latest version **1.0.5** (published 2019-04-01) · ISC license · 0 weekly downloads

## Install

```sh
npm install query-methods
pnpm add query-methods
yarn add query-methods
bun add query-methods
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.5 |
| Published | 2019-04-01 |
| First published | 2019-03-31 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 39.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Fernando Kuteken |
| Maintainers | kuteken |

## Links

- npm: https://www.npmjs.com/package/query-methods
- Repository: https://github.com/fskuteken/query-methods
- Homepage: https://github.com/fskuteken/query-methods#readme
- Issues: https://github.com/fskuteken/query-methods/issues
- npm.io page: https://npm.io/package/query-methods

## Recent versions

- 1.0.5 (latest) — 2019-04-01
- 1.0.4 — 2019-04-01
- 1.0.3 — 2019-04-01
- 1.0.2 — 2019-04-01
- 1.0.1 — 2019-04-01
- 1.0.0 — 2019-03-31

## README

# Query methods

[![CircleCI](https://circleci.com/gh/fskuteken/query-methods.svg?style=svg)](https://circleci.com/gh/fskuteken/query-methods)

This library provides JavaScript methods to perform query operations like
selecting, filtering, grouping and ordering on arrays of objects.

The `Query` class receives an array in its constructor and has several methods
that can be used to build the desired result.

```javascript
import { Query } from 'query-methods';

const elements = [
  { id: 1, key: 'a', value: 10 },
  { id: 2, key: 'b', value: 20 },
  { id: 3, key: 'c', value: 30 }
];

const query = new Query(elements);

query.select('id').where({ value: v => v > 15}).all;
// [{ id: 2 }, { id: 3 }]
```

## Install

Query methods is available as a package in npm:

```bash
npm install query-methods
```

## Methods

### Getters

The `Query` class has the following getters:

* `all`: returns every result of the query;
* `first`: returns the first result of the query;
* `last`: returns the last result of the query;

Example:
```javascript
const query = new Query([1, 2, 3]);

query.all;   // [1, 2, 3]
query.first; // 1
query.last;  // 3
```

### Methods

The `Query` class has the following methods:
* `select`: the values used to select attributes;
* `where`: the conditions used to filter the results;
* `group`: the attributes used to group the results;
* `order`: the methods used to order the results;
* `limit`: limits the result of the query;
* `offset`: offsets the result of the query;

#### Select

It accepts _strings_, _objects_ and _functions_ as arguments:

* `String`: the name of the attribute to select;
* `Object`:
  * `key`: the name of the attribute in the result;
  * `value`:
    * `String`: the name of the attribute to select;
    * `Function`: receives the element and returns the value to select;
* `Function`: receives the element and returns the value to select. The name of the function is used as the name of the attribute in the result.

```javascript
const query = new Query([{ id: 1, key: 'a', price: 10 }]);

const result = query.select(
  'key',
  {
    fullPrice: 'price',
    discountedPrice: e => e.price * 0.9;
  }
  function custom(e) { return `${e.id}-${e.key}` }
).all;
// [{ key: 'a', fullPrice: 10, discountedPrice: 9, custom: '1-a' }]
```

#### Where

It accepts _functions_ and _objects_ as arguments:


* `Function`: receives the element and returns a `Boolean` indicating if it should be selected;
* `Object`:
  * `key`: the name of the attribute to check;
  * `value`:
    * `Function`: receives the element's attribute and returns a `Boolean`;
    * other value: checks if the attribute equals the value.

```javascript
const query = new Query(elements);

const result = query.where(
  element => element.price < 100, // elements with price < 100
  {
    key: 'a',                     // elements with key === 'a'
    price: price => price > 10    // elements with price > 10
  }
).all;
```

The library provides some functions that help building queries with where statements:

* `eq`: Checks if an attribute is equal to a value;
* `not`: Checks if an attribute is not equal to a value;
* `lt`: Checks if an attribute is less than a value;
* `lte`: Checks if an attribute is less than or equal to a value;
* `gt`: Checks if an attribute is greater than a value;
* `gte`: Checks if an attribute is greater than or equal to a value;

```javascript
const result = query.where({
  key: not('a'), // key !=== 'a'
  price: lt(100) // price < 100
}).all;
```


#### Group

It accepts the same arguments as the `select` methods:

* `String`: the name of the attribute to group by;
* `Object`:
  * `key`: the name of the attribute in the result;
  * `value`:
    * `String`: the name of the attribute to group;
    * `Function`: receives the element and returns the value to group;
* `Function`: receives the element and returns the value to group. The name of the function is used as the name of the attribute in the result.

The grouped values are returned in the result by default.

```javascript
const elements = [{ key: 'A' }, { key: 'a' }];
let query, result;

query = new Query(elements);
result = query.group('key').all;
// [{ key: 'A' }, { key: 'a' }]

query = new Query(elements);
result = query.group({ uppercaseKey: e => e.key.toUpperCase() }).all;
// [{ uppercaseKey: 'A' }]
```

#### Order

It accepts _functions_ and _objects_ as arguments:

* `Function`: receives two elements and should return a negative number, zero or a positive number indicating the order of the elements, similar to the native `Array#sort` method;
* `Object`:
  * `key`: the name of the attribute used to order;
  * `value`: a `Function` that receives two attributes and should return the number indicating their order.

```javascript
const query = new Query(elements);

const result = query.order({
  key: (a, b) => a.localeCompare(b),
  price: (a, b) => a - b
}).all;
```

The library provides some functions to help building queries with order:

* `asc.number`: orders numbers in an ascending order;
* `asc.string`: orders strings in an ascending order;
* `desc.number`: orders numbers in an descending order;
* `desc.string`: orders strings in an descending order;

```javascript
const result = query.order({
  key: asc.string,
  price: desc.number
}).all;
```

#### Limit and offset

Each method accepts a single integer as argument:

* `limit`: limits the quantity of elements in the result;
* `offset`: skips the first elements of the result.

```javascript
const query = new Query([1, 2, 3, 4]);

const result = query.limit(2).offset(1).all;
// [2, 3]
```

#### Aggregate functions

When the query receives `group` arguments, the behavior of the `select` method changes, allowing it to use aggregate functions:

```javascript
const query = new Query([
  { price: 10 },
  { price: 20 }
]);

const result = query.group('key').select({
  maxPrice: elements => {
    const prices = elements.map(e => e.price);
    return Math.max(...prices);
  }
}).all;
```

The library provides some aggregate functions to make group queries easier:

* `min`: accepts the name of the attribute to calculate the minimum;
* `max`: accepts the name of the attribute to calculate the maximum;
* `sum`: accepts the name of the attribute to calculate the total;
* `average`: accepts the name of the attribute to calculate the average;
* `count`: counts the number of elements in the group;

```javascript
const query = new Query([
  { key: 'a', price: 10 },
  { key: 'a', price: 20 },
  { key: 'b', price: 30 },
  { key: 'b', price: 40 }
]);

const result = query.group('key').select({
  maxPrice: max('price'),
  minPrice: min('price'),
  averagePrice: average('price'),
  sumPrice: sum('price'),
  count: count()
}).all;

// [{ key: 'a', maxPrice: 20, minPrice: 10, ... }, { key: 'b', ... }]
```

---
_Source: https://npm.io/package/query-methods · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
