matcher.js 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. const log = require('./log')
  2. // Match an object with a query.
  3. // Ex: Querying a.* on { a: { b: 1, c: 2 }}} -> [1, 2]
  4. // We stop recusively attempting if isLeaf(node) returns true.
  5. module.exports = function match (object, query, isLeaf) {
  6. isLeaf = isLeaf || function () { return true }
  7. query = query || '*'
  8. query = query.split('.')
  9. return doMatch(object, query, isLeaf)
  10. }
  11. function nameMatches (query, name) {
  12. /// __group is a reserved name.
  13. if (name === '__group') {
  14. return false
  15. }
  16. if (query === '*') {
  17. return true
  18. } else if (query === name) {
  19. return true
  20. }
  21. return false
  22. }
  23. function doMatch (object, query, isLeaf) {
  24. query = query || []
  25. let result = []
  26. let level = query.shift() || '*'
  27. for (let [ key, value ] of Object.entries(object)) {
  28. // If the name doesn't match, continue.
  29. if (!nameMatches(level, key)) {
  30. continue
  31. }
  32. if (isLeaf(value)) {
  33. // If it's a leaf, add a result.
  34. result.push(value)
  35. } else {
  36. // Otherwise, add child results.
  37. // We must slice(0) the query, so that it is duplicated.
  38. result = [...result, ...doMatch(value, query.slice(0), isLeaf)]
  39. }
  40. }
  41. return result
  42. }