SQL样式JOIN对JSON数据

Luk*_*ure 16 javascript jquery json join

有效加入JSON数据有什么方法吗?假设我们有两个JSON数据集:

{"COLORS":[[1,red],[2,yellow],[3,orange]]}

{"FRUITS":[[1,apple],[2,banana],[3,orange]]}
Run Code Online (Sandbox Code Playgroud)

我想将其转变为以下客户端:

{"NEW_FRUITS":[[1,apple,red],[2,banana,yellow],[3,orange,orange]]}
Run Code Online (Sandbox Code Playgroud)

请记住,这里将有数千条记录,其中包含更复杂的数据结构.jQuery和vanilla javascript都很好.还要记住,可能有没有颜色的水果和水果的颜色.

注意:为简单起见,假设两个数据集的顺序相同,但第二个数据集可能有间隙.

Ray*_*oal 8

事实上,将有数千个输入和键不一定被订购意味着你最好的选择(至少对于大型对象)是先按键排序.对于尺寸小于约5的物体,蛮力n ^ 2方法就足够了.

然后,您可以通过并行遍历两个数组来写出结果,并在输出时将新的"记录"附加到输出中.这种排序然后合并的想法是一个相对强大的想法,并经常使用.如果您不想先排序,可以将元素添加到优先级队列,然后合并.然后,排序然后合并方法在概念上可能更简单; 如果性能很重要,你应该做一些分析.

对于没有水果和水果的颜色 - 没有颜色,我认为写null缺失值就足够了.如果相同的键在颜色或水果中出现不止一次,您可以任意选择一个,或者抛出异常.

ADDENDUM我也做了一个小提琴:http://jsfiddle.net/LuLMz/.它不对键的顺序做出任何假设,也不对数组的相对长度做任何假设.唯一的假设是字段的名称以及每个子数组有两个元素的事实.


age*_*hun 8

Alasql JavaScript SQL库在一行中完全满足您的需求:

 <script src="alasql.min.js"></script>
 <script>
    var data = { COLORS: [[1,"red"],[2,"yellow"],[3,"orange"]],            
                 FRUITS: [[1,"apple"],[2,"banana"],[3,"orange"]]};

    data.NEW_FRUITS = alasql('SELECT MATRIX COLORS.[0], COLORS.[1], FRUITS.[1] AS [2] \
         FROM ? AS COLORS JOIN ? AS FRUITS ON COLORS.[0] = FRUITS.[0]',
         [data.COLORS, data.FRUITS]);
 </script>
Run Code Online (Sandbox Code Playgroud)

您可以在jsFiddle中使用此示例.

这是一个SQL表达式,其中:

  • SELECT - 选择运算符
  • MATRIX - 修饰符,whci将结果集从对象数组转换为数组数组
  • 颜色.[0] - COLORS数组的第一列等
  • 水果.1 AS 2 - 数组FRUITS的第二列将作为第三列存储在结果记录集中
  • 从?AS COLORS - SQL语句中名为COLORS的参数的数据数组
  • 加入?ON ... - 加入
  • [data.COLORS,data.FRUITS] - 带数据数组的参数


Sha*_*oli 3

没有直接的方法,但您可以编写逻辑来获取像这样的组合对象。由于“apple、red、banana...”都是字符串,因此应将它们用单引号或双引号括起来。

如果您可以通过为缺失的项目添加空值来匹配 COLORS 和 FRUITS 配置数组,那么您可以使用此方法。

工作演示

var colors = {"COLORS":[[1,'red'],[2,'yellow'],[3,'orange']]}

var fruits = {"FRUITS":[[1,'apple'],[2,'banana'],[3,'orange']]}

var newFruits = {"NEW_FRUITS": [] }

//Just to make sure both arrays are the same size, otherwise the logic will break
if(colors.COLORS.length == fruits.FRUITS.length){
    var temp;
    $.each(fruits.FRUITS, function(i){
        temp = this;
        temp.push(colors.COLORS[i][2]);
        newFruits.NEW_FRUITS.push(temp);
    });
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您可以创建colorsfruits配置为对象数组,而不是数组数组,则可以尝试此解决方案。此处元素的顺序无关紧要,但数组大小仍应匹配。

工作演示

var colors = {"COLORS":[ {"1": 'red'}, { "2": 'yellow'}, {"3":'orange'}]}

var fruits = {"FRUITS":[ {"1":'apple'}, { "2": 'banana'}, {"3":'orange'}]}

var newFruits = {"NEW_FRUITS": [] }

if(colors.COLORS.length == fruits.FRUITS.length){
    var temp, first;
    $.each(fruits.FRUITS, function(i){
        for(first in this)break;
        temp = {};
        temp[first] = [];
        temp[first].push(this[first]);
        temp[first].push(colors.COLORS[i][first]);
        newFruits.NEW_FRUITS.push(temp);
    });
}
Run Code Online (Sandbox Code Playgroud)