123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- const _ = require('lodash');
- if (!Object.hasOwn) {
- Object.hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
- }
- const IS_UNDEFINED = {
- isUndefined: true,
- };
- function addToSelection(salty, item, i) {
- salty._selectedItems.push(item);
- salty._selectedIndexes.push(i);
- }
- function selectAllItems(salty) {
- salty._selectedItems = salty._items.slice();
- salty._selectedIndexes = [...Array(salty._items.length).keys()];
- }
- function createSelection(salty) {
- salty._selectedIndexes = [];
- salty._selectedItems = [];
- }
- function eraseSelection(salty) {
- salty._selectedIndexes = null;
- salty._selectedItems = null;
- }
- function finderWithFunction(salty, func) {
- createSelection(salty);
- salty._items.forEach((item, i) => {
- if (func.bind(item)()) {
- addToSelection(salty, item, i);
- }
- });
- return salty;
- }
- function finderWithMatcher(salty, ...args) {
- let item;
- let matches;
- const len = salty._items.length;
- const matcher = _.defaults({}, ...args);
- const matcherKeys = Object.keys(matcher);
- let matcherValue;
-
- if (matcherKeys.length === 0) {
- selectAllItems(salty);
- } else {
- createSelection(salty);
- for (let i = 0; i < len; i++) {
- matches = true;
- item = salty._items[i];
- for (const key of matcherKeys) {
- matcherValue = matcher[key];
- if (_.isMatch(matcherValue, IS_UNDEFINED)) {
- matches = _.isUndefined(item[key]);
- } else if (Array.isArray(matcherValue)) {
- if (!matcherValue.includes(item[key])) {
- matches = false;
- }
- } else if (matcherValue !== item[key]) {
- matches = false;
- }
- if (matches === false) {
- break;
- }
- }
- if (matches) {
- addToSelection(salty, item, i);
- }
- }
- }
- return salty;
- }
- function finder(salty, ...args) {
- if (args.length && _.isFunction(args[0])) {
- return finderWithFunction(salty, args[0]);
- } else {
- return finderWithMatcher(salty, ...args);
- }
- }
- function isNullOrUndefined(value) {
- return _.isNull(value) || _.isUndefined(value);
- }
- function sorter(items, keys) {
- keys = keys.split(',').map((key) => key.trim());
- keys.reverse();
- for (const key of keys) {
-
-
-
-
-
-
-
-
- items.sort((a, b) => {
- const aValue = a[key];
- const bValue = b[key];
- if (isNullOrUndefined(aValue) || isNullOrUndefined(bValue)) {
-
- if (!isNullOrUndefined(aValue)) {
- return -1;
- }
- if (!isNullOrUndefined(bValue)) {
- return 1;
- }
-
- if (_.isNull(aValue) && _.isUndefined(bValue)) {
- return -1;
- }
- if (_.isUndefined(aValue) && _.isNull(bValue)) {
- return 1;
- }
-
- if (_.isUndefined(aValue) && _.isUndefined(bValue)) {
- if (Object.hasOwn(a, key)) {
- return -1;
- }
- if (Object.hasOwn(b, key)) {
- return 1;
- }
- }
-
- return 0;
- }
-
- if (aValue < bValue) {
- return -1;
- }
- if (aValue > bValue) {
- return 1;
- }
- return 0;
- });
- }
- return true;
- }
- function makeDb(salty) {
-
- const db = (...args) => finder(salty, ...args);
- db.sort = (keys) => sorter(salty._items, keys);
- return db;
- }
- class Salty {
- constructor(items) {
- this._items = items ? items.slice() : [];
- eraseSelection(this);
- return makeDb(this);
- }
- each(func) {
- this._selectedItems.forEach((item, i) => func(item, i));
- return this;
- }
- get() {
- return this._selectedItems.slice();
- }
- remove() {
- let removedItems = 0;
- if (this._selectedIndexes && this._selectedIndexes.length) {
- removedItems = this._selectedIndexes.length;
- this._items = this._items.filter((_item, i) => !this._selectedIndexes.includes(i));
- }
-
- createSelection(this);
- return removedItems;
- }
- }
- module.exports = Salty;
|