TomFrost / Jexl

Javascript Expression Language: Powerful context-based expression parser and evaluator
MIT License
561 stars 92 forks source link

Support for referencing individual properties in a collection #71

Closed austinkelleher closed 4 years ago

austinkelleher commented 4 years ago

This may already be supported, but if so, I couldn't find the syntax in the documentation. Currently, Jexl supports filtering using the data[.name == 'Austin'].id syntax. I'd like to be able to basically map an array, so that we can return a subset of properties.

Here are two examples of what I'm trying to accomplish:

Sample internal map functionality:

const jexl = require('jexl');

// It would be great if this would return:
// [{ properties: { id: "abc" } }, { properties: { id: "def" } }]
const result = jexl.evalSync("data[.properties]", {
  data: [
    {
     name: 'John',
      properties: {
        id: 'abc'
      }
    },
    {
      name: 'Jane',
      properties: {
        id: 'def'
      }
    }
  ]
});

Sample mapping of sub properties:

const jexl = require('jexl');

// [{ id: "abc" }, { id: "def" }]
const result = jexl.evalSync("data[.properties.id]", {
  data: [
    {
     name: 'John',
      properties: {
        id: 'abc'
      }
    },
    {
      name: 'Jane',
      properties: {
        id: 'def'
      }
    }
  ]
});

Thoughts @TomFrost?

TomFrost commented 4 years ago

This is super slick. I think this is probably better addressed by a transform rather than a change to the expression language, though, simply because others' use cases are likely to vary a lot on this. I'll 100% reconsider that if this gets overwhelming support!

Something like:

jexl.addTransform('mapTo', (collection, prop) => collection.map(elem => elem[prop]))
jexl.evalSync("data|mapTo('properties')", context)