合并多对一的对象列表

时间:2015-06-18 23:43:40

标签: javascript sql arrays sqlite associative-array

我目前有两个数据库表,代表多对一关系。活动,具有ID(整数,自动增量,主键)和名称(varchar(255),非null);和ActivitySlugs,它们具有ID(与上面相同),slugname(非null varchar)和activity_id(Activities.id的外键)。

目前我应该得到所有活动和所有slu的列表(作为一个列表),以便它看起来像这样:

[
    {id: 1, name: "long name", slugs: ["nick", "names"]},
    {id: 2, name: "foobar", slugs: ["foo", "bar"]}
]

天真的解决方案(以及我能想到的唯一解决方案)是在每个表上执行“SELECT *”,然后合并它们,但随后我得到的数据如下:

activities = [
    {id: 1, name: "long name"},
    {id: 2, name: "foobar"}
]
slugs = [
    {id: 1, slugname: "nick", activity_id: 1},
    {id: 2, slugname: "names", activity_id: 1},
    {id: 3, slugname: "foo", activity_id: 2},
    {id: 4, slugname: "bar", activity_id: 2}
]

然后我可以迭代两者并添加它们:

activities.forEach(function(activity) {
    slugs = [];
    activitySlugs.forEach(function(slug) {
        if (slug.activity_id == activity.id) {
            slugs.push(slug.name);
        }
    });
    activity.slugs = slugs;
);

这感觉笨拙,缓慢和未精炼。它当然不会扩展。不幸的是,我似乎无法找到一种更好的方法来让它们像这样的数组合并为多对一。

2 个答案:

答案 0 :(得分:2)

您可以构建id2activity地图以通过其ID访问任何活动:

var id2activity = {};
activities.forEach(function(activity) {
    activity.slugs = [];
    id2activity[activity.id] = activity;
);

activitySlugs.forEach(function(slug) {
    id2activity[slug.activity_id].slugs.push(slug.name);
});

答案 1 :(得分:0)

由于slug只能属于一个活动,你应该遍历slugs并附加到某个活动对象。

var activities = [
    {id: 1, name: "long name"},
    {id: 2, name: "foobar"}
];
var slugs = [
    {id: 1, slugname: "nick", activity_id: 1},
    {id: 2, slugname: "names", activity_id: 1},
    {id: 3, slugname: "foo", activity_id: 2},
    {id: 4, slugname: "bar", activity_id: 2}
];

slugs.forEach(function(slug) {
    var a = activities.filter(function(a){return a.id==slug.activity_id;}); 
    // should check if it exists - assume that it does
    if (a[0].slugs == undefined) {
      a[0].slugs = [slug.id];
    } else {
      a[0].slugs.push(slug.id);
    }
});