合并多对一的对象列表
Merge many-to-one list of objects
我目前有两个数据库table,代表多对一的关系。具有 ID(整数、自动增量、主键)和名称(varchar(255),非空)的活动;和 ActivitySlugs,它们有一个 ID(与上面相同)、一个 slugname(不是 null varchar)和一个 activity_id(Activities.id 的外键)。
目前我应该获得所有活动及其所有 slug 的列表(作为一个列表),因此它看起来像这样:
[
{id: 1, name: "long name", slugs: ["nick", "names"]},
{id: 2, name: "foobar", slugs: ["foo", "bar"]}
]
天真的解决方案(也是我能想到的唯一一个)是对每个 table 执行 "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;
);
这感觉笨拙、缓慢且不精炼。它肯定不会扩展。不幸的是,我似乎找不到更好的方法让它们与这样的数组进行多对一合并。
由于 slug 只能属于一个 activity,因此您应该遍历 slug 并附加到某个 activity 对象。
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);
}
});
您可以构造一个 id2activity 映射以通过其 id 访问任何 activity:
var id2activity = {};
activities.forEach(function(activity) {
activity.slugs = [];
id2activity[activity.id] = activity;
);
activitySlugs.forEach(function(slug) {
id2activity[slug.activity_id].slugs.push(slug.name);
});
我目前有两个数据库table,代表多对一的关系。具有 ID(整数、自动增量、主键)和名称(varchar(255),非空)的活动;和 ActivitySlugs,它们有一个 ID(与上面相同)、一个 slugname(不是 null varchar)和一个 activity_id(Activities.id 的外键)。
目前我应该获得所有活动及其所有 slug 的列表(作为一个列表),因此它看起来像这样:
[
{id: 1, name: "long name", slugs: ["nick", "names"]},
{id: 2, name: "foobar", slugs: ["foo", "bar"]}
]
天真的解决方案(也是我能想到的唯一一个)是对每个 table 执行 "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;
);
这感觉笨拙、缓慢且不精炼。它肯定不会扩展。不幸的是,我似乎找不到更好的方法让它们与这样的数组进行多对一合并。
由于 slug 只能属于一个 activity,因此您应该遍历 slug 并附加到某个 activity 对象。
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);
}
});
您可以构造一个 id2activity 映射以通过其 id 访问任何 activity:
var id2activity = {};
activities.forEach(function(activity) {
activity.slugs = [];
id2activity[activity.id] = activity;
);
activitySlugs.forEach(function(slug) {
id2activity[slug.activity_id].slugs.push(slug.name);
});