15

在我的日常工作中,我碰巧编写了类似于 LINQ 表达式的链式 javascript 函数来查询 JSON 结果。

var Result = from(obj1).as("x").where("x.id=5").groupby("x.status").having(count("x.status") > 5).select("x.status");

它完美地工作并给出了预期的结果。

我想知道如果代码是这样编写的(以更易读的方式),这看起来很棒

var Result = from obj1 as x where x.status
groupby x.status having count(x.status)  > 5
select x.status;

有没有办法做到这一点?

干杯

拉梅什维尔

4

8 回答 8

20

不,JavaScript 不支持这一点。

但这看起来也不错:

var Result =  from(obj1)
             .as("x")
             .where("x.id=5")
             .groupby("x.status")
             .having(count("x.status") > 5)
             .select("x.status");
于 2009-09-01T10:06:54.467 回答
6

大多数人坚持尝试从他们最喜欢的语言内部进行元编程。如果语言不能很好地支持元编程,那就不行了。其他答案观察到JavaScript没有。

解决此问题的一种方法是使用 程序转换工具从语言外部进行元编程。这样的工具可以解析源代码,并对其进行任意转换(这就是元编程所做的),然后吐出修改后的程序。

如果您有一个可以解析任意语言的通用程序转换系统,那么您可以使用/使用您喜欢的任何语言进行元编程。请参阅我们的DMS Software Reengineering Toolkit了解此类工具,该工具具有强大的 C、C++、Java、C#、COBOL、PHP 和 ECMAScript 前端以及许多其他编程语言,并已用于所有这些的元编程。

在您的情况下,您希望使用 SQL 查询的新语法扩展 JavaScript 语法,然后将它们转换为纯 JavaScript。(这很像意图编程)DMS 将让您轻松构建带有附加规则的 JavaScript 方言,然后您可以使用其程序转换功能生成等效的标准 Javascript。

话虽如此,我不是“地球上每个程序员的自定义语法”的忠实粉丝,这是故意编程导致恕我直言的地方。

如果有大量用户认为这很有价值,这是一件好事。这个想法可能是也可能不是其中之一;问题的一部分是你不做实验就无法发现,而且它可能无法获得足够的社会牵引力。

于 2010-02-26T18:16:01.477 回答
5

虽然不是您想要的,但可以用 javascript 编写解析器,只需解析查询(存储为字符串)然后执行它。例如,使用http://jscc.jmksf.com/之类的库(毫无疑问还有其他库),实现起来应该不会太难。

但是您在问题中的内容看起来已经很棒了,我不确定您为什么希望它看起来像您建议的那样。

于 2009-09-01T10:44:02.647 回答
5

考虑到这个问题是几年前提出的,我会根据当前的技术尝试添加更多内容。

从 ECMAScript 6 开始,现在通过SymbolReflectProxy对象在某种意义上支持元编程。

通过在网上搜索,我找到了一系列关于这个主题的非常有趣的文章,由 Keith Kirkel 撰写:

ES6 中的元编程:符号及其出色的原因

简而言之,符号是可以添加到对象内部的新原语(实际上不是属性),并且对于将元编程属性传递给它非常方便。符号都是关于通过修改现有类来改变它们的行为(实现中的反射)。

ES6 中的元编程:第 2 部分 - 反射

简而言之,Reflect 实际上是所有那些仅通过 JavaScript 引擎内部可用的“内部方法”的集合,现在暴露在一个方便的对象中。它的用法类似于 Java 和 C# 的反射功能。它们用于发现有关您的代码的非常低级的信息(通过自省进行反射)。

ES6 中的元编程:第 3 部分 - 代理

简而言之,Proxies 是处理程序对象,负责包装对象并通过陷阱(Reflection through intercession)拦截其行为。

当然,这些对象提供了特定的元编程能力,与元编程语言相比限制性更强,但仍然可以提供方便的基本元编程方式,实际上主要是通过反射实践。

最后,值得一提的是,在 JavaScript 中的分阶段元编程方面正在进行一些值得注意的研究工作。

于 2016-09-13T11:12:00.257 回答
3

好吧,在您的代码示例中:

var Result = from(obj1)
            .as("x")
            .where("x.id=5")
            .groupby("x.status")
            .having(count("x.status") > 5)
            .select("x.status");

我看到的唯一问题(除了select用作标识符)是您将谓词嵌入为函数参数。你必须把它变成一个函数:

            .having(function(x){ return x.status > 5; })

JavaScript 有闭包和动态类型,所以你可以在其中做一些非常漂亮和优雅的事情。只是让你知道。

于 2010-07-20T02:09:04.127 回答
2

在纯 JS 中,你不能。但是使用正确的预处理器是可能的。

你可以用sweet.js宏或(上帝原谅我)GPP做类似的事情。

于 2015-02-04T11:27:21.970 回答
1

您想要的是将 javascript 解析器更改为 SQL 解析器。它不是为此而创建的,javascript 语法不允许您这样做。

你所拥有的是 90% 像 SQL(它直接映射到它),以及 100% 有效的 javascript,这是一个了不起的成就。我对标题中问题的回答是:是的,元编程是可能的,但不,它不会给你一个 SQL 解析器,因为它必须使用 javascript 语法。

于 2009-09-01T10:57:56.830 回答
0

如果你有 JSON 数据,也许你想要类似JSONPath的东西。我在http://www.json.org/找到了这个。如果它不完全是您所需要的,那么许多其他工具都可以从那里链接到。

(这也在进行中:http ://docs.dojocampus.org/dojox/json/query )

于 2009-09-01T10:37:54.170 回答