2

I'm trying to investigate different approaches to an idea I have brewing in my head and I'm not really sure how to search for what I'm trying to do.

I have a series of functions. These all transform the same JSON format (schema) (with differing data). Into different objects (different schemas).

For example I might have JSON like...

{
  heading: "Fogmeister",
  type: "person",
  body_text: "iOS developer",
  sections: [
    {
      heading: 'Describing a transform between two sets of data... a "meta-transform"?',
      type: "post",
      body_text: "I'm trying to investigate..."
    },
    {
      // other post
    }
  ]
}

And I would want to transform it to a user object like...

{
  name: "Fogmeister",
  profile: "iOS developer",
  posts: [
    { title: 'Describing a transform between two sets of data... a "meta-transform"?' },
    { title: 'Other title' }
  ]
}

But I might have some different JSON like...

{
  heading: 'Describing a transform between two sets of data... a "meta-transform"?',
  type: "post",
  body_text: "I'm trying to investigate...",
  sections: [
    {
      heading: null,
      type: "answer",
      body_text: "What you're looking for is..."
    },
    {
      // other answer
    }
  ]
}

And I would want to transform it to a post object like...

{
  title: 'Describing a transform between two sets of data... a "meta-transform"?',
  body: "I'm trying to investigate...",
  answers: [
    { body_text: "What you're looking for is..." },
    { body_text: 'Other answer' }
  ]
}

Hopefully from this small example you can see that the input schema is the same but the output schema might be very different.

I currently have different functions for mapping each different type. But I'm trying to see if I can come up with a way where I can describe the mapping between the input and output and then put that into an object (or something).

That way I can have a single function that uses this Mapping object to transform the data.

But... I don't know if this is something that has a name already. It's sort of a meta-transform as I want to be able to describe the transform rather than doing the transform myself.

Is there something I can google that will provide more information about this sort of programming?

I'm not looking for code that will do this. More just material I can read around the subject so I can do it myself.

Thanks

Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • 1
    I'd be very interested to see if such a mapping language/schema exists, though it seems that in order that the language be sufficiently complex to be capable of handling these mappings, it may not be particularly less complicated than doing the same thing manually in javascript – OliverRadini May 21 '19 at 13:58
  • 1
    @OliverRadini oh, I have no doubt that it would be complex. But hopefully the complexity can exist inside a single function/object/system that I can then pass a "relatively" simple `meta-transform` object that will allow the complexity to do the transform. If so, that would allow me to add new transforms to new types with relative ease. ...hopefully. – Fogmeister May 21 '19 at 14:00
  • 1
    Interesting question. Some googling on my own took me to this answer: https://stackoverflow.com/a/17413374/628699. The appspot demo on that lib looks like it might be what you're after – imjared May 21 '19 at 14:14
  • 1
    Also potentially relevant: https://stackoverflow.com/questions/13068267/json-to-json-transformer – OliverRadini May 21 '19 at 14:16
  • Excellent, places to start. Thanks :D I'll be back to update you on how it goes :D – Fogmeister May 21 '19 at 14:17

2 Answers2

1

Sounds like you are describing a schema transpiler something that reads in a schema, and builds an abstract syntax tree from it. You can then read that tree to build up a new schema of any fashion you like, allowing you to describe different shapes from the same AST.

This repo explains expertly, how to build a compiler with JavaScript. with a schema (since it's JSON) it would be a lot easier since all you have to do is parse the JSON and iterate the objects rather than read each character in a file.

https://github.com/jamiebuilds/the-super-tiny-compiler

Remember, the aim is to build something that can generate a clean independent AST that something else can consume. Good luck

Jay
  • 1,033
  • 1
  • 18
  • 31
0

A more practical approach by using an object for the pattern and a function for getting mapped properties.

function convert(pattern, object) {
    return Object.assign({}, ...Object
        .entries(object)
        .map(([k, v]) => k in pattern
            ? typeof pattern[k] === 'object'
                ? { [pattern[k].name]: pattern[k].fn(v) }
                : { [pattern[k]]: v }
            : {}
        )
    );
}

var pattern1 = {
        heading: 'name',
        body_text: 'profile',
        sections: { name: 'posts', fn: array => array.map(o => convert({ heading: 'title' }, o)) }
    },
    input1 = { heading: "Fogmeister", type: "person", body_text: "iOS developer", sections: [{ heading: 'Describing a transform between two sets of data... a "meta-transform"?', type: "post", body_text: "I'm trying to investigate..." }, {}] };

console.log(convert(pattern1, input1));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392