Skip to content

Commit

Permalink
Improve pick()
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Mar 13, 2022
1 parent 3a74895 commit bcd6ef0
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 11 deletions.
9 changes: 3 additions & 6 deletions src/config/normalize/lib/wild_wild_path/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ export const set = function (target, queryOrPaths, value) {
// Ignore properties when one of their ancestors was matched too.
// Uses `iterate()` to keep memory consumption low.
export const reduceParents = function (target, queryOrPaths, setFunc) {
// eslint-disable-next-line fp/no-let
let newTarget = target

const paths = []

// eslint-disable-next-line fp/no-loops
Expand All @@ -24,12 +21,12 @@ export const reduceParents = function (target, queryOrPaths, setFunc) {
if (!parentIsSet(paths, path)) {
// eslint-disable-next-line fp/no-mutating-methods
paths.push(path)
// eslint-disable-next-line fp/no-mutation
newTarget = setFunc(newTarget, path, 0)
// eslint-disable-next-line fp/no-mutation, no-param-reassign
target = setFunc(target, path, 0)
}
}

return newTarget
return target
}

// If both a parent and a child property are set, the parent prevails
Expand Down
41 changes: 40 additions & 1 deletion src/config/normalize/lib/wild_wild_path_utils/common.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { list } from '../wild_wild_path/main.js'
import { list, iterate, parent } from '../wild_wild_path/main.js'

// `list()` but without missing entries
export const listExisting = function (target, queryOrPath) {
Expand All @@ -8,3 +8,42 @@ export const listExisting = function (target, queryOrPath) {
const isExisting = function ({ missing }) {
return !missing
}

// Modify a target object multiple times for each matched property.
// Ignore properties when one of their ancestors was matched too.
// Uses `iterate()` to keep memory consumption low.
export const reduceParents = function ({
target,
newTarget,
queryOrPaths,
setFunc,
condition = returnTrue,
}) {
const paths = []

// eslint-disable-next-line fp/no-loops
for (const entry of iterate(target, queryOrPaths)) {
// eslint-disable-next-line max-depth
if (shouldUseEntry(entry, paths, condition)) {
// eslint-disable-next-line fp/no-mutating-methods
paths.push(entry.path)
// eslint-disable-next-line fp/no-mutation, no-param-reassign
newTarget = setFunc(newTarget, entry, 0)
}
}

return newTarget
}

const returnTrue = function () {
return true
}

const shouldUseEntry = function (entry, paths, condition) {
return !entry.missing && !parentIsSet(paths, entry.path) && condition(entry)
}

// If both a parent and a child property are set, the parent prevails
const parentIsSet = function (paths, path) {
return paths.some((previousPath) => parent(previousPath, path))
}
12 changes: 8 additions & 4 deletions src/config/normalize/lib/wild_wild_path_utils/pick.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { set } from '../wild_wild_path/main.js'

import { listExisting } from './common.js'
import { listExisting, reduceParents } from './common.js'

// Returns an object with only the properties being queried.
export const pick = function (target, queryOrPath) {
const entries = listExisting(target, queryOrPath)
return entries.reduce(pickEntry, {})
export const pick = function (target, queryOrPaths) {
return reduceParents({
target,
newTarget: {},
queryOrPaths,
setFunc: pickEntry,
})
}

const pickEntry = function (target, { path, value }) {
Expand Down

0 comments on commit bcd6ef0

Please sign in to comment.