我已经搜索了一段时间试图找到这个问题的答案,因为我想有人会遇到这种情况。如果已经有答案,请指出我正确的方向。我有一系列包含书籍的对象。这些书籍存储在数据库中,可以有一个或多个作者。对于writers表中的每个writer,都有book_id(FK),writer_name和review_id(FK)的列。因此,如果书上有多个作者,则每个作者都有一行包含除名称之外的相同信息。以下是来自DB的JSON响应的示例:
var data = [
{"id": 1, "writer" : "John Joseph Doe", "review_id" : 4},
{"id": 1, "writer" : "Daniel Smith", "review_id" : 4},
{"id": 1, "writer" : "Thomas Edward Jones", "review_id" : 4},
{"id": 2, "writer" : "Erin Davis", "review_id" : 5},
{"id": 2, "writer" : "Jill Steinberg", "review_id" : 5},
{"id": 2, "writer" : "Laurie Beth Jennings", "review_id" : 5},
{"id": 3, "writer" : "Emma Jean Williams", "review_id" : 3},
{"id": 3, "writer" : "Mary Joe Williams", "review_id" : 3},
{"id": 3, "writer" : "Helen Andrews", "review_id" : 3},
{"id": 3, "writer" : "Samantha Jones", "review_id" : 3}
];
我想过滤这个数组,以便最终得到3个对象,每个对应一个,没有重复值,每个编写器连接成逗号分隔的字符串。像这样:
var data = [
{"id": 1, "writer" : "John Joseph Doe, Daniel Smith, Thomas Edward Jones", "review_id" : 4},
{"id": 2, "writer" : "Erin Davis, Jill Steinberg, Laurie Beth Jennings", "review_id" : 5},
{"id": 3, "writer" : "Emma Jean Williams, Mary Joe Williams, Helen Andrews, Samantha Jones", "review_id" : 3}
];
所以我尝试创建一个使用for循环和'first'变量的函数来根据它的id来跟踪我所处的对象。我的逻辑是将每个编写器添加到具有唯一ID的每个对象的第一个实例,然后在添加编写器后删除具有相同id的所有进程对象。因此,我为每个书籍ID留下了一个对象,并且用逗号分隔了一系列连接的作家。结果接近我正在寻找的,但我无法做到正确。我不确定是否从阵列中删除对象是我的问题,或者我是否采取了完全错误的方法。这是一个工作小提琴:http://jsfiddle.net/mlabita37/Lvc0u55v/8987/ 。表格上方有一个textarea,我用它作为“控制台”来显示最终数据数组,只需展开即可查看完整结果。
以下是该代码的一些片段:
HTML:
<div ng-controller="BookCtrl">
<table class="table table-striped">
<thead>
<tr>
<th>Book ID</th>
<th>Writer</th>
<th>Review ID</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="book in books">
<td>{{ book.id }}</td>
<td>{{ book.writer }}</td>
<td>{{ book.review_id }}</td>
<textarea>{{ books }}</textarea>
</tr>
</tbody>
控制器:
var data = [
{"id": 1, "writer" : "John Joseph Doe", "review_id" : 4},
{"id": 1, "writer" : "Daniel Smith", "review_id" : 4},
{"id": 1, "writer" : "Thomas Edward Jones", "review_id" : 4},
{"id": 2, "writer" : "Erin Davis", "review_id" : 5},
{"id": 2, "writer" : "Jill Steinberg", "review_id" : 5},
{"id": 2, "writer" : "Laurie Beth Jennings", "review_id" : 5},
{"id": 3, "writer" : "Emma Jean Williams", "review_id" : 3},
{"id": 3, "writer" : "Mary Joe Williams", "review_id" : 3},
{"id": 3, "writer" : "Helen Andrews", "review_id" : 3},
{"id": 3, "writer" : "Samantha Jones", "review_id" : 3}
];
combine = function(data){
var first = data[0];
for(var i = 1; i < data.length; i++){
if(data[i].id === first.id){
first.writer = first.writer + ", " + data[i].writer;
data.splice(i, 1);
}
if(data[i].id !== first.id){
first = data[i];
var j = i+1;
if(data[j].id === first.id){
first.writer = first.writer + ", " + data[j].writer;
data.splice(j, 1);
}
}
}
};
combine(data);
$scope.books = data;
我的另一个想法是使用过滤器,但我对它们没有多少经验,也不知道这是否是更好的方法。我也不确定这是否可以/应该在我的MySQL查询中处理,或者在后端PHP中处理。我的印象是这最好在前端处理。
答案 0 :(得分:1)
var data = [
{"id": 1, "writer" : "John Joseph Doe", "review_id" : 4},
{"id": 1, "writer" : "Daniel Smith", "review_id" : 4},
{"id": 1, "writer" : "Thomas Edward Jones", "review_id" : 4},
{"id": 2, "writer" : "Erin Davis", "review_id" : 5},
{"id": 2, "writer" : "Jill Steinberg", "review_id" : 5},
{"id": 2, "writer" : "Laurie Beth Jennings", "review_id" : 5},
{"id": 3, "writer" : "Emma Jean Williams", "review_id" : 3},
{"id": 3, "writer" : "Mary Joe Williams", "review_id" : 3},
{"id": 3, "writer" : "Helen Andrews", "review_id" : 3},
{"id": 3, "writer" : "Samantha Jones", "review_id" : 3}
];
function existsAt(array, key, value) {
for (var i = 0; i < array.length; i++) {
if (array[i][key] == value) {
return i;
}
}
return false;
}
var _data = [];
_data.push(data[0]);
for (var i = 1; i < data.length; i++) {
var alreadyExistsAt = existsAt(_data, 'id', data[i].id);
if (alreadyExistsAt !== false) {
_data[alreadyExistsAt].writer += ', ' + data[i].writer;
} else {
_data.push(data[i]);
}
}
document.body.innerHTML = JSON.stringify(_data);
&#13;
答案 1 :(得分:1)
我希望代码中的变量名称使其具有相当自我解释性。
forEach
循环从完整的评论列表中依次选择每个评论(即currReview
)。forEach
循环遍历每个预先存在的连锁书评对象(即prevReviewsForThisBook
...首先为空)。此内循环确定当前评论是否针对已经至少有一次评论的图书:
writer
属性以包括新编写者。 请注意,您id
的{{1}}始终与book_id
相同。这真的是你想要的吗?似乎其中一个是冗余/不必要的,或者其中一个是错误地计算/确定的。后者似乎有可能。例如,John Joseph Doe完成的审核的review_id
和Daniel Smith所做的审核的review_id
是否都具有相同的值,4?我认为那些是单独的评论,因此应该有不同的review_id
值,即使它们都具有相同的review_id
/ id
值(因为这两个人都审阅了同一本书) 。这个问题不是回答这个问题的核心问题,但你可能想重新考虑一下。
book_id
&#13;