Skip to content

Commit

Permalink
Remove duplicates
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Mar 13, 2022
1 parent b8829b7 commit dde58af
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
32 changes: 29 additions & 3 deletions src/config/normalize/lib/wild_wild_path/iterate.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { groupBy } from '../../../../utils/group.js'

import { equalsSimple, isSameToken } from './parsing/compare.js'
import { parse } from './parsing/parse.js'
import { serialize } from './parsing/serialize.js'
import { getObjectTokenType } from './tokens/main.js'
Expand All @@ -20,13 +21,14 @@ export const iterate = function (target, queryOrPaths) {
}

const iterateLevel = function (entries, index) {
const parentEntries = entries.filter(({ path }) => path.length === index)
const entriesA = removeDuplicates(entries)
const parentEntries = entriesA.filter(({ path }) => path.length === index)

if (parentEntries.length === entries.length) {
if (parentEntries.length === entriesA.length) {
return parentEntries
}

const levelEntries = entries
const levelEntries = entriesA
.filter(({ path }) => path.length !== index)
.flatMap((entry) => iteratePath(entry, index))

Expand All @@ -44,6 +46,30 @@ const iterateLevel = function (entries, index) {
return [...childEntries, ...parentEntries]
}

const removeDuplicates = function (entries) {
return entries.length === 1 ? entries : entries.filter(isNotDuplicate)
}

const isNotDuplicate = function (entryA, index, entries) {
return entries.every(
(entryB, indexB) => index <= indexB || !isDuplicate(entryA, entryB),
)
}

const isDuplicate = function (
{ props: propsA, path: pathA },
{ props: propsB, path: pathB },
) {
return (
equalsSimple(propsA, propsB) &&
pathA.length === pathB.length &&
pathA.every(
(tokenA, index) =>
index < propsA.length || isSameToken(tokenA, pathB[index]),
)
)
}

// Iteration among siglings is not sorted, for performance reasons.
// - Consumers can sort it through using the `query` property
// However, iteration is guaranteed to return child entries before parent ones.
Expand Down
10 changes: 9 additions & 1 deletion src/config/normalize/lib/wild_wild_path/parsing/compare.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ export const equals = function (queryOrPathsA, queryOrPathsB) {
)
}

// Check if two simple paths are equal
export const equalsSimple = function (simplePathA, simplePathB) {
return (
simplePathA.length === simplePathB.length &&
simplePathA.every((prop, index) => simplePathB[index] === prop)
)
}

// Check if a query is a parent of another.
// With unions, it checks if any query is a parent of any of the other one.
// The comparison is currently token type-wise.
Expand Down Expand Up @@ -61,7 +69,7 @@ const isSamePath = function (pathA, pathB) {
)
}

const isSameToken = function (tokenA, tokenB) {
export const isSameToken = function (tokenA, tokenB) {
const tokenTypeA = getObjectTokenType(tokenA)
const tokenTypeB = getObjectTokenType(tokenB)
return tokenTypeA === tokenTypeB && tokenTypeA.equals(tokenA, tokenB)
Expand Down

0 comments on commit dde58af

Please sign in to comment.