cheetah-framework
Version:
Cheetah Framework JS used in all our applications
231 lines (190 loc) • 5.28 kB
JavaScript
function _seek (data, path, _default) {
if (typeof path === 'object') {
return _.flattenDeep(_.map(path, k => _.seek(data, k)))
}
let wildcardIndex = path.indexOf('*.')
if (wildcardIndex === -1) {
const a = _.get(data, path)
if (a !== undefined) {
return a
}
}
let wildcardLength = 2
if (wildcardIndex > 0) {
wildcardLength = 3
wildcardIndex--
}
return _.flattenDeep(_.map(
wildcardIndex === 0 ? data : _.get(data, path.substring(0, wildcardIndex)),
partialData => _.seek(partialData, path.substring(wildcardIndex + wildcardLength))
))
}
export default {
// Like _.get, with wildcard (.*.)
seek (data, path, _default) {
const result = _seek(data, path)
if (typeof _default !== 'undefined' && !result.length) {
return _default
}
return result
},
valuesDeep (data) {
data = _.map(data, d => {
if (typeof d === 'object') {
return _.valuesDeep(d)
}
return d
})
return _.values(data)
},
findDeep (data, path, predicate) {
return _.filter(_.seek(data, path), predicate)
},
toUrl (string) {
return _.deburr(string).toLowerCase().replace(/[\s]+/g, '-').replace(/[^a-z0-9-]+/g, '')
},
pascalCase: _.flow(_.camelCase, _.upperFirst),
cartesianProductOf (...args) {
return _.reduce(args, function (a, b) {
return _.flatten(_.map(a, function (x) {
return _.map(b, function (y) {
return x.concat([y])
})
}), true)
}, [[]])
},
filterMap (data, filterPredicate, mapPredicate) {
const filterIteratee = _.iteratee(filterPredicate)
const mapIteratee = _.iteratee(mapPredicate)
return _.reduce(data, (filteredMappedData, datum, key) => {
if (filterIteratee(datum, key)) {
filteredMappedData.push(mapIteratee(datum, key))
}
return filteredMappedData
}, [])
},
mapFilter (data, mapPredicate, filterPredicate = _.identity) {
const mapIteratee = _.iteratee(mapPredicate)
const filterIteratee = _.iteratee(filterPredicate)
return _.reduce(data, (filteredMappedData, datum, key) => {
const mappedDatum = mapIteratee(datum, key)
if (filterIteratee(mappedDatum, key)) {
filteredMappedData.push(mapIteratee(datum, key))
}
return filteredMappedData
}, [])
},
unFlat (data) {
const unFlattenData = {}
_.keys(data).forEach(key => {
_.set(unFlattenData, key, data[key])
})
return unFlattenData
},
plural (word, revert) {
const plural = {
'(quiz)$': '$1zes',
'^(ox)$': '$1en',
'([m|l])ouse$': '$1ice',
'(matr|vert|ind)ix|ex$': '$1ices',
'(x|ch|ss|sh)$': '$1es',
'([^aeiouy]|qu)y$': '$1ies',
'(hive)$': '$1s',
'(?:([^f])fe|([lr])f)$': '$1$2ves',
'(shea|lea|loa|thie)f$': '$1ves',
'sis$': 'ses',
'([ti])um$': '$1a',
'(tomat|potat|ech|her|vet)o$': '$1oes',
'(bu)s$': '$1ses',
'(alias)$': '$1es',
'(octop)us$': '$1i',
'(ax|test)is$': '$1es',
'(us)$': '$1es',
'([^s]+)$': '$1s'
}
const singular = {
'(quiz)zes$': '$1',
'(matr)ices$': '$1ix',
'(vert|ind)ices$': '$1ex',
'^(ox)en$': '$1',
'(alias)es$': '$1',
'(octop|vir)i$': '$1us',
'(cris|ax|test)es$': '$1is',
'(shoe)s$': '$1',
'(o)es$': '$1',
'(bus)es$': '$1',
'([m|l])ice$': '$1ouse',
'(x|ch|ss|sh)es$': '$1',
'(m)ovies$': '$1ovie',
'(s)eries$': '$1eries',
'([^aeiouy]|qu)ies$': '$1y',
'([lr])ves$': '$1f',
'(tive)s$': '$1',
'(hive)s$': '$1',
'(li|wi|kni)ves$': '$1fe',
'(shea|loa|lea|thie)ves$': '$1f',
'(^analy)ses$': '$1sis',
'((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$': '$1$2sis',
'([ti])a$': '$1um',
'(n)ews$': '$1ews',
'(h|bl)ouses$': '$1ouse',
'(corpse)s$': '$1',
'(us)es$': '$1',
's$': ''
}
const irregular = {
'move': 'moves',
'foot': 'feet',
'goose': 'geese',
'sex': 'sexes',
'child': 'children',
'man': 'men',
'tooth': 'teeth',
'person': 'people'
}
const uncountable = [
'sheep',
'fish',
'deer',
'moose',
'series',
'species',
'money',
'rice',
'information',
'equipment',
]
// save some time in the case that singular and plural are the same
if (uncountable.indexOf(word.toLowerCase()) >= 0) {
return word
}
// check for irregular forms
for (const iword in irregular) {
let pattern, replace
if (revert) {
pattern = new RegExp(irregular[iword] + '$', 'i')
replace = iword
} else {
pattern = new RegExp(iword + '$', 'i')
replace = irregular[iword]
}
if (pattern.test(word)) {
return word.replace(pattern, replace)
}
}
let array
if (revert) {
array = singular
} else {
array = plural
}
// check for matches using regular expressions
for (const reg in array) {
const pattern = new RegExp(reg, 'i')
if (pattern.test(word)) {
return word.replace(pattern, array[reg])
}
}
return word
}
}