描述两组数据之间的转换...“元转换”?

时间:2019-05-21 13:54:47

标签: javascript metaprogramming transformation

我正在尝试研究在脑海中酝酿的一个想法的不同方法,但我不确定如何搜索我想做的事情。

我有一系列功能。这些都转换相同的JSON格式(模式)(具有不同的数据)。放入不同的对象(不同的模式)。

例如,我可能有类似JSON的...

{
  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
    }
  ]
}

我想将其转换为类似...的用户对象

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

但是我可能有一些不同的JSON,例如...

{
  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
    }
  ]
}

我想将其转换为类似...的帖子对象

{
  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' }
  ]
}

希望从这个小例子中可以看到输入模式是相同的,但是输出模式可能会非常不同。

我目前具有用于映射每种不同类型的不同功能。但是我正在尝试看看是否可以提出一种方法,可以describe在输入和输出之间进行映射,然后将其放入对象(或某些对象)中。

这样,我可以拥有一个使用此Mapping对象转换数据的函数。

但是...我不知道这是否已经有名称。这有点像meta-transform,因为我希望能够描述转换而不是自己进行转换。

我可以在Google上搜索一些东西,以提供有关此类编程的更多信息吗?

我不是在寻找可以做到这一点的代码。我可以阅读更多有关该主题的材料,以便我自己完成。

谢谢

2 个答案:

答案 0 :(得分:1)

类似您的声音描述了模式编译器,该编译器会读取模式,并从中构建抽象的语法树。然后,您可以阅读该树以建立您喜欢的任何方式的新架构,从而可以描述来自同一AST的不同形状。

此存储库专业地说明了如何使用JavaScript构建编译器。使用模式(因为它是JSON)会容易得多,因为您要做的就是解析JSON并迭代对象,而不是读取文件中的每个字符。

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

请记住,目标是构建可以生成干净独立的AST的东西,而其他东西可以消耗掉它。祝你好运

答案 1 :(得分:0)

通过使用对象作为模式并使用函数来获取映射属性的更实用方法。

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; }