Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Wildcards #43

Open
Carpenter0100 opened this issue May 20, 2022 · 2 comments
Open

Question: Wildcards #43

Carpenter0100 opened this issue May 20, 2022 · 2 comments
Labels

Comments

@Carpenter0100
Copy link

Hi,
Is it possible to use wildcards?
Sth. like this: "array.value.*.array.value"

Thank you

@colinodell
Copy link
Contributor

No, unfortunately this library doesn't directly support searching with wildcards. But it shouldn't be too hard to implement something like that yourself :)

For example, you could split that path by the * to first get all the values at array.value, and then iterate through those to see if any match the rest of the path.

I doubt this library would add native support for wildcards since virtually all operations are designed to operate on a single fixed path (not multiple paths at once).

@curzio-della-santa
Copy link

curzio-della-santa commented Mar 22, 2024

One operation that could support wildcard without changing the whole design is the remove.

This is really useful for the scope which I'm using the library:
remove specific keys before serialization of data for a comparison before/after.

I've written a small extension to the remove:

    /**
     * {@inheritdoc}
     */
    public function remove(string $key): void
    {
        $currentValue =& $this->data;
        $keyPath = self::keyToPathArray($key);

        $endKey = array_pop($keyPath);
        foreach ($keyPath as $currentKey) {
            if ($currentKey === '*') { /** @todo Add is_iterable($currentValue) in the condition? */
                foreach (array_keys($currentValue) as $concreteKey) {
                    // Replace first occurrence of .*. with the concrete key
                    // https://stackoverflow.com/questions/1252693/using-str-replace-so-that-it-only-acts-on-the-first-match
                    $this->remove(implode(sprintf('.%s.', $concreteKey), explode('.*.', $key, 2)));
                }
            }

            if (!isset($currentValue[$currentKey])) {
                return;
            }
            $currentValue =& $currentValue[$currentKey];
        }
        unset($currentValue[$endKey]);
    }

In my scenario this is enough, but for your library you should adapt the code for:

  • Multiple separators e.g. use for the recursion
     $this->remove(
         preg_replace(
             sprintf('[%1$s]\*[%1$s]', implode('', self::DELIMITERS)), // If '-' would be a delimiter, need to be last
             sprintf('.%s.', $concreteKey),
             $key,
             1
         )
     );
  • Keys beginning with wildcard
  • Keys ending with wildcard (which makes no sense .. but you never know)
  • Custom wildcard character
  • etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants