使用JavaScript/jQuery对JSON数据进行分组和排序

3

我有一份JSON数据,需要做类似于分组的操作。我之前在这里问过这个问题,但是没有得到满意的答案,所以这次我想更深入地解释一下。

首先,请问有人能够解释一下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    

任何想法/建议/方向/想法都将是巨大的帮助。

1
JavaScript 没有 groupby/orderby,您需要使用库吗?如果您在谈论 SQL,请提供查询语句。 - Bergi
谢谢您的回复。这里没有SQL,我只有JSON数据。我知道在JavaScript中没有groupby/orderby。有没有办法实现这个目标?不,我不能使用库,因为我们开发了自己的内部语言。我知道库并不重要,但由于公司政策,我不能使用第三方JavaScript库。 - ravi
3个回答

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

如果我想要新对象的格式如下怎么办?:{username: "Jhon", userinfo: [{...}]} ? - Q_ro
1
@Q_ro 然后你可以对生成的对象进行后处理,例如使用 http://underscorejs.org/#pairs 或 map,但这已经是另一个问题了。 - Andrejs

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

谢谢Vivin。我会先进行排序,然后将整个对象传递给group by,这样我就可以得到精确的顺序。我猜你的解决方案会奏效。 - ravi

0
使用一级函数创建通用的按键规约器和排序器。我将从我的先前回答中获取规约器。这样,您可以按任何键进行排序和分组,类似于在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);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接