Skip to content

Instantly share code, notes, and snippets.

@mpalpha
Last active February 14, 2019 20:35
Show Gist options
  • Save mpalpha/84885ec88fa86431bc193ce63b365e46 to your computer and use it in GitHub Desktop.
Save mpalpha/84885ec88fa86431bc193ce63b365e46 to your computer and use it in GitHub Desktop.
sort an array by specified key values matching a given array of values. (used for metalsmith-collections, and metalsmith-collections-tree)

Sort an array by specified key values matching a given array of values. (used for metalsmith-collections, and metalsmith-collections-tree)

metalsmith-collections

metalsmith-collections-tree

metalsmith example:

const sortByArray = require('./sortByArray.js');

... 
          use(collections({
            'cool-products': {
              pattern: ['products/cool-products/*'],
              sortBy: sortByArray('name', [
                'c-page-name',
                'a-page-name',
                'b-page-name'
              ])
            }
          })
...
'use strict';
/**
* Generate a custom sort method for given starting `order`. After the given
* order, it will ignore casing and put periods last.
*
* sort descending by key with array items first.
* sortByArray('title', ['Home']);
*
* That is passed:
*
* - Home
* - About
* - JavaScript
* - HTML
* - CSS
* - .NET
*
* Would guarantee that 'Home' ends up first, with the casing in 'iOS'
* ignored so that it falls in the normal alphabetical order, and puts '.NET'
* last since it starts with a period.
*
* alternatively you may ommit the sort array.
* sort descending by key if no array is passed.
* sorter('title');
*
* @param {string} keyName
* @param {Array} order
* @return {Function}
*/
module.exports = (k = 'name', s = []) => (a, b) => {
let k1 = a[k], k2 = b[k];
if (!k1 && !k2) return 0;
if (!k1) return 1;
if (!k2) return -1;
let is1 = s.indexOf(k1), is2 = s.indexOf(k2);
if (~is1 && ~is2) return is1 < is2 ? -1 : is2 < is1 ? 1 : 0;
if (~is1) return -1;
if (~is2) return 1;
k1 = k1.toLowerCase();
k2 = k2.toLowerCase();
// move matches with . to the end
return '.' === k1[0] ? 1 : '.' === k2[0] || k1 < k2 ? -1 : k2 < k1 ? 1 : 0;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment