<commit_before>
/*
 * This model represents a collection of
 * related items (e.g. pages) for each
 * CollectionItem (e.g. "feature")
 * in a Collection (e.g. "tags")
 */

// node_modules
var List = require('collections/list');
var traverse = require('traverse');
var _ = require('lodash');

/*
 * Default way of finding an item is by
 * the name or src property
 */
var defaultEquals = function (a, b) {
  var aKey = a.name || a.src;
  var bKey = b.name || b.src;
  return aKey === bKey;
};

/*
 * Default way of comparing two items
 * is by the name or src property
 */
var defaultCompare = function (a, b) {
  var aKey = a.name || a.src;
  var bKey = b.name || b.src;

  if (aKey > bKey) {
    return 1;
  } else if (aKey < bKey) {
    return -1;
  } else {
    return 0;
  }
};

/*
 * When adding an item to the collection
 * make sure it's accessiable by it's name
 */
var createGetterSetter = function (itemCollection, item) {
  var key = item.name || item.src;
  if (itemCollection.hasOwnProperty(key) === false) {
    Object.defineProperty(itemCollection, key, {
      enumerable: true,
      get: function () {
        return itemCollection.get(key);
      },
      set: function(value) {
        itemCollection.set(value);
      }
    });
  }
};

var createGetter = function (obj, property, getFn) {
  if (obj.hasOwnProperty(property) === false) {
    Object.defineProperty(obj, property, {
      get: getFn
    });
  }
};

var ItemCollection = module.exports = function (options) {
  this.options = options || {};
  this.items = new List(this.options.items || [], this.options.equals || defaultEquals);

  // expose some getters
  createGetter(this, 'length', function () {
    return this.items.length;
  });
};

ItemCollection.prototype.add = function (item) {
  var key = item.name || item.src;
  if (this.items.has(key) === false) {
    this.items.add(item);
    createGetterSetter(this, item);
  }
};

ItemCollection.prototype.get = function (search, by) {
  if (_.isFunction(search)) {
    by = search;
  }

  if (_.isFunction(by)) {
    var results = this.items.find(search, by);
    return results && results.value;
  }

  if (typeof search === 'string') {
    if (by && typeof by === 'string') {
      return this.findByMetadata(search, by);
    }
    var item = {name: search};
    if (this.items.has(item)) {
      return this.items.get(item);
    }
  }
  return null;
};

ItemCollection.prototype.sorted = function(compare, by, order) {
  compare = compare || defaultCompare;<commit_msg>adding ability to just pass in a string for sorting<commit_after>
/*
 * This model represents a collection of
 * related items (e.g. pages) for each
 * CollectionItem (e.g. "feature")
 * in a Collection (e.g. "tags")
 */

// node_modules
var List = require('collections/list');
var traverse = require('traverse');
var _ = require('lodash');

/*
 * Default way of finding an item is by
 * the name or src property
 */
var defaultEquals = function (a, b) {
  var aKey = a.name || a.src;
  var bKey = b.name || b.src;
  return aKey === bKey;
};

/*
 * Default way of comparing two items
 * is by the name or src property
 */
var defaultCompare = function (a, b) {
  var aKey = a.name || a.src;
  var bKey = b.name || b.src;

  if (aKey > bKey) {
    return 1;
  } else if (aKey < bKey) {
    return -1;
  } else {
    return 0;
  }
};

/*
 * When adding an item to the collection
 * make sure it's accessiable by it's name
 */
var createGetterSetter = function (itemCollection, item) {
  var key = item.name || item.src;
  if (itemCollection.hasOwnProperty(key) === false) {
    Object.defineProperty(itemCollection, key, {
      enumerable: true,
      get: function () {
        return itemCollection.get(key);
      },
      set: function(value) {
        itemCollection.set(value);
      }
    });
  }
};

var createGetter = function (obj, property, getFn) {
  if (obj.hasOwnProperty(property) === false) {
    Object.defineProperty(obj, property, {
      get: getFn
    });
  }
};

var ItemCollection = module.exports = function (options) {
  this.options = options || {};
  this.items = new List(this.options.items || [], this.options.equals || defaultEquals);

  // expose some getters
  createGetter(this, 'length', function () {
    return this.items.length;
  });
};

ItemCollection.prototype.add = function (item) {
  var key = item.name || item.src;
  if (this.items.has(key) === false) {
    this.items.add(item);
    createGetterSetter(this, item);
  }
};

ItemCollection.prototype.get = function (search, by) {
  if (_.isFunction(search)) {
    by = search;
  }

  if (_.isFunction(by)) {
    var results = this.items.find(search, by);
    return results && results.value;
  }

  if (typeof search === 'string') {
    if (by && typeof by === 'string') {
      return this.findByMetadata(search, by);
    }
    var item = {name: search};
    if (this.items.has(item)) {
      return this.items.get(item);
    }
  }
  return null;
};

ItemCollection.prototype.sorted = function(compare, by, order) {
  compare = compare || defaultCompare;
  if (_.isString(compare)) {
    var search = compare;
    compare = function (a, b) {
      if (typeof a.metadata[search] !== 'undefined' && typeof b.metadata[search] !== 'undefined') {
        if (a.metadata[search] > b.metadata[search]) {
          return 1;
        } else if (a.metadata[search] < b.metadata[search]) {
          return -1;
        }
      }
      return 0;
    }
  }
{'fraction_non_alphanumeric': 0.15035799522673032, 'fraction_numerical': 0.001652285661832201, 'mean_word_length': 2.8693181818181817, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3911858', 'n_tokens_mistral': 1786, 'n_tokens_neox': 1769, 'n_words': 493}