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

Unexpected multiple traversals #7

Open
simlu opened this issue Jul 24, 2022 · 1 comment
Open

Unexpected multiple traversals #7

simlu opened this issue Jul 24, 2022 · 1 comment

Comments

@simlu
Copy link

simlu commented Jul 24, 2022

So in the readme it states:

[...] whereas Nimma, for the most time, doesn't really care whether you supply it with 10s or 100s of paths. [...]

Unfortunately multiple paths mean multiple accesses when using Nimma. This is a huge deal when many input paths are given or slow getters are used.

This should definitely be mentioned in the Readme. It is probably the biggest and most fundamental difference to object-scan.

Click to show Test Case
import Nimma from 'nimma';
import objectScan from 'object-scan';

class AccessLogger {
  constructor(obj) {
    const logs = {};
    const prepare = (o) => {
      const entries = Object.entries(o);
      const result = {};
      for (let i = 0; i < entries.length; i += 1) {
        const [k, v] = entries[i];
        const value = prepare(v);
        result[k] = value;
        Object.defineProperty(result, k, {
          get() {
            if (!(k in logs)) {
              logs[k] = 0;
            }
            logs[k] += 1;
            return value;
          }
        });
      }
      return result;
    };
    this.logs = logs;
    this.obj = prepare(obj);
  }

  reset() {
    const logs = { ...this.logs };
    Object.keys(this.logs).forEach((k) => {
      delete this.logs[k];
    });
    return logs;
  }
}

const accessLogger = new AccessLogger({
  a: {
    b: {
      c: {},
      d: {},
      e: {}
    }
  }
});
const { obj } = accessLogger;

const keysNimma = [
  '$.a.b.c',
  '$..*',
  '$.a.b.d',
  '$.a.b.e',
  '$.a.*.e',
  '$..e',
  '$.*.*',
  '$..b.c',
  '$.a.b'
];
const keysObjectScan = keysNimma
  .map((k) => (k.startsWith('$..') ? `**${k.slice(2)}` : k.slice(2)))

const testNimma = () => {
  const callbacks = [];
  new Nimma(keysNimma).query(obj, keysNimma.reduce((p, k) => ({
    ...p,
    [k]({ value, path }) {
      callbacks.push([path.join('.'), k, value]);
    }
  }), {}));
  return { callbacks, access: accessLogger.reset() };
};

const testObjectScan = () => {
  const callbacks = objectScan(keysObjectScan, {
    joined: true,
    filterFn: ({ matchedBy, key, value, context }) => {
      matchedBy.forEach((m) => {
        context.push([key, m, value]);
      });
    }
  })(obj, []);
  return { callbacks, access: accessLogger.reset() };
};

console.log(testNimma());
/*
{
  callbacks: [
    [ 'a.b.c', '$.a.b.c', {} ],
    [ 'a.b.d', '$.a.b.d', {} ],
    [ 'a.b.e', '$.a.b.e', {} ],
    [ 'a.b', '$.a.b', [Object] ],
    [ 'a', '$..*', [Object] ],
    [ 'a.b', '$..*', [Object] ],
    [ 'a.b', '$.*.*', [Object] ],
    [ 'a.b.c', '$..*', {} ],
    [ 'a.b.c', '$..b.c', {} ],
    [ 'a.b.d', '$..*', {} ],
    [ 'a.b.e', '$..*', {} ],
    [ 'a.b.e', '$.a.*.e', {} ],
    [ 'a.b.e', '$..e', {} ]
  ],
  access: { a: 10, b: 9, c: 3, d: 3, e: 3 }
}
*/
console.log(testObjectScan());
/*
{
  callbacks: [
    [ 'a.b.e', 'a.b.e', {} ],
    [ 'a.b.e', 'a.*.e', {} ],
    [ 'a.b.e', '**.*', {} ],
    [ 'a.b.e', '**.e', {} ],
    [ 'a.b.d', 'a.b.d', {} ],
    [ 'a.b.d', '**.*', {} ],
    [ 'a.b.c', 'a.b.c', {} ],
    [ 'a.b.c', '**.*', {} ],
    [ 'a.b.c', '**.b.c', {} ],
    [ 'a.b', 'a.b', [Object] ],
    [ 'a.b', '**.*', [Object] ],
    [ 'a.b', '*.*', [Object] ],
    [ 'a', '**.*', [Object] ]
  ],
  access: { a: 2, b: 2, e: 2, d: 2, c: 2 }
}
 */
@simlu simlu mentioned this issue Jul 24, 2022
@simlu simlu changed the title Multiple traversals 😕 Unexpected multiple traversals Jul 24, 2022
@simlu
Copy link
Author

simlu commented Jul 24, 2022

I've added a test suite now that highlights the difference:
https://github.com/blackflux/object-scan/pull/1753/files

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

No branches or pull requests

1 participant