使用基于id

时间:2016-09-01 03:02:26

标签: javascript php mysql angularjs arrays

我已经搜索了一段时间试图找到这个问题的答案,因为我想有人会遇到这种情况。如果已经有答案,请指出我正确的方向。我有一系列包含书籍的对象。这些书籍存储在数据库中,可以有一个或多个作者。对于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中处理。我的印象是这最好在前端处理。

2 个答案:

答案 0 :(得分:1)

&#13;
&#13;
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;
&#13;
&#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值(因为这两个人都审阅了同一本书) 。这个问题不是回答这个问题的核心问题,但你可能想重新考虑一下。

&#13;
&#13;
book_id
&#13;
&#13;
&#13;