使用javascript / jquery按On / order by On JSON数据分组

时间:2012-06-18 20:51:22

标签: javascript jquery json

我有一个JSON数据,我需要做像group by这样的事情,我之前问过这个问题,但我没有得到任何满意的答案所以这次我想深入解释。

首先,任何人都可以解释我在javascript中groupbyorderby之间的区别,因为在sql中我们需要使用聚合函数才能使用group by。但我不想要像聚合函数那样的东西。在这里,我提供了一个非常简单的JSON数据和输出,我正在寻找。

所有作者姓名应为sortby字母数字顺序。

JSON数据:

var myObject = {
    "Apps": [
        {
            "Name": "app1",
            "id": "1",
            "groups": [
                {
                    "id": "1",
                    "name": "test group 1",
                    "category": "clinical note",
                    "author": "RRP"
                }, {
                    "id": "2",
                    "name": "test group 2",
                    "category": "clinical image",
                    "author": "LKP"
                }, {
                    "id": "3",
                    "name": "test group 3",
                    "category": "clinical document",
                    "author": "RRP"
                }, {
                    "id": "4",
                    "name": "test group 4",
                    "category": "clinical note",
                    "author": "John"
                }
            ]
        }
    ]
}

预期产出:

John
  4 testgroup4 clinicalnote 
RRP
  1 testgroup1  clinicalnote
  3 testgroup3  clinicaldocument
LKP
  2 testgroup2 clinicalimage    

任何想法/建议/方向/想法都会有很大的帮助。

3 个答案:

答案 0 :(得分:3)

您可以使用Underscore.js轻松完成此操作:

_.chain(myObject.Apps[0].groups).sortBy("author").groupBy("author").value();

输出JSON对象:

{
 "John":[{"id":"4","name":"test group 4","category":"clinical note","author":"John"}],
 "LKP":[{"id":"2","name":"test group 2","category":"clinical image","author":"LKP"}],
 "RRP":[{"id":"1","name":"test group 1","category":"clinical note","author":"RRP"},{"id":"3","name":"test group 3","category":"clinical document","author":"RRP"}]
}

答案 1 :(得分:1)

此方案中Javascript中没有内置的“group by”或“order by”。您将不得不手动执行此操作。这样的事情可能会有所帮助:

var groups = myObject.Apps[0].groups;
var authors = {};
var authorNames = [];

for(var i = 0; i < groups.length; i++) {
    var group = groups[i];    

    if(typeof authors[group.author] === "undefined") {
        authors[group.author] = [];
        authorNames.push(group.author);
        authorNames.sort();
    }

    authors[group.author].push({
        id: group.id,
        name: group.name,
        category: group.category
    });       
}

通常在关联数组中,您并不真正关心键的顺序,而且通常无法保证迭代顺序。我在这里做的是按排序顺序维护一个单独的名称数组。然后我可以迭代该数组并使用这些值从关联数组中获取关联的对象。

查看fiddle

答案 2 :(得分:0)

使用first class functions创建按密钥归约器和分类器分类的通用分组。我将从previous answer of mine中获取减速器。这样,您就可以按照自己喜欢的任何键进行排序和分组,就像在SQL中一样。

const groupBy = key => (result,current) => {
  const item = Object.assign({},current);
  if (typeof result[current[key]] == 'undefined'){
    result[current[key]] = [item];
  }else{
    result[current[key]].push(item);
  }
  return result;
};

const stringSortBy = key => (a,b) => {
   const sa = a[key];
   const sb = b[key];
   return sa < sb ? -1 : +(sa > sb);
};

const myObject = {
    "Apps": [
        {
            "Name": "app1",
            "id": "1",
            "groups": [
                {
                    "id": "1",
                    "name": "test group 1",
                    "category": "clinical note",
                    "author": "RRP"
                }, {
                    "id": "2",
                    "name": "test group 2",
                    "category": "clinical image",
                    "author": "LKP"
                }, {
                    "id": "3",
                    "name": "test group 3",
                    "category": "clinical document",
                    "author": "RRP"
                }, {
                    "id": "4",
                    "name": "test group 4",
                    "category": "clinical note",
                    "author": "John"
                }
            ]
        }
    ]
}

const categories = myObject.Apps[0].groups.reduce(groupBy('category'),{});
console.log(categories);
const sorted = myObject.Apps[0].groups.sort(stringSortBy('author'));
console.log(sorted);