Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对线程化对话进行排序_Javascript_Python_Sql_Postgresql_Sorting - Fatal编程技术网

Javascript 对线程化对话进行排序

Javascript 对线程化对话进行排序,javascript,python,sql,postgresql,sorting,Javascript,Python,Sql,Postgresql,Sorting,我不知道该怎么画这个,但现在开始 这是一个排序算法问题 我必须使用的工具是服务器上的PostgresSQL和python(2.6)以及浏览器端的javascript/jquery 我需要将描述线程化对话的数据从postgres DB移动到web页面。数据以时间顺序开始,我想以线程的形式显示 记录数很小-返回的消息不应超过100条 因此,作为一个简单的例子,想象一下表格: ID Reply_To Text === ======== ======================

我不知道该怎么画这个,但现在开始

这是一个排序算法问题

我必须使用的工具是服务器上的PostgresSQL和python(2.6)以及浏览器端的javascript/jquery

我需要将描述线程化对话的数据从postgres DB移动到web页面。数据以时间顺序开始,我想以线程的形式显示

记录数很小-返回的消息不应超过100条

因此,作为一个简单的例子,想象一下表格:

ID     Reply_To   Text
===    ========   =============================
1      0          Hello World
2      0          Make me a sandwich
3      1          Hello back
4      2          No chance
5      1          Who are you?
6      5          Me of course
我想达到的终点是

  • 你好,世界
    • 回头见
    • 你是谁
      • 当然是我
  • 给我做个三明治
    • 不可能
或者,换一种说法

ID     Reply_To   Text
===    ========   =============================
1      0          Hello World
3      1          Hello back
5      1          Who are you?
6      5          Me of course
2      0          Make me a sandwich
4      2          No chance
我并不想要一个完整的解决方案,所有的ajax、json和格式化的东西我都很乐意去做

我只是有一些问题需要我的头脑去思考如何以最整洁的方式来管理分类

SQL?pythonJavascript

我目前正在Javascript中使用数组排序(没有比我的python技能异常薄弱更好的原因了)

编辑 目前我正处于这样的状态:

function byThread(a,b) {
  if (a.reply > b.id && a.reply != 0){
    console.log("Compared id=" + a.id + " with id=" + b.id + " and returned -1 ")
    return -1;
  }
  if (a.id > b.reply && b.reply != 0 ){
    console.log("Compared id=" + a.id + " with id=" + b.id + " and returned 1 ")
    return 1;
  }
  console.log("Compared id=" + a.id + " with id=" + b.id + " and returned 0 ")
  return 0;
}
msg.sort(byThread);

它令人沮丧地接近了

我尝试用纯sql来实现这一点,因为我认为这就是逻辑应该属于的地方。您需要做的是找到从父级到子级的ID列表,并按顺序排列。幸运的是,postgres具有可以排序的数组类型,因此我们可以使用递归CTE:

with recursive threaded(id, reply_to, message, order_path) as (
    select 
        parent.id, 
        parent.reply_to, 
        parent.message, 
        NULL::int[] || parent.id -- create an 1-element array with the parent id
    from conversation parent
    where parent.reply_to is null
    UNION ALL
    select 
        reply.id, 
        reply.reply_to, 
        reply.message, 
        t.order_path || reply.id -- append the reply id to the current path
    from threaded t
    join conversation reply on t.id = reply.reply_to
    where reply.reply_to is not null
)
select * from threaded order by order_path;
结果是:

1    NULL    "Hello World"          "{1}"
3    1       "Hello Back"           "{1,3}"
5    1       "Who are you?"         "{1,5}"
6    5       "Me of course"         "{1,5,6}"
2    NULL    "Make me a sandwich"   "{2}"
4    2       "No Chance"            "{2,4}"
我不确定这将如何执行,所以你一定要在你的真实数据集上测试和分析它,以确保它是好的。如果不是,也许您可以考虑重新构造数据,并研究在数据库中存储“树”数据的不同方法。django有一个名为的库,可以有效地存储和检索树。这个概念通常适用于数据库,但用于拉出树并确保它们保持完整的算法需要更改应用程序逻辑,由库更好地处理

编辑:


我应该提到,我最初只是将“order_path”的顶级id用作一个数字。这让我使用了一组ID来保证整个订单。

您可以在JS端尝试类似的方法。因为它在回复中包含回复,所以从
corporated

var convo = [{id: 1, replyTo: 0, text: "hello world"}, 
             {id: 2, replyTo: 0, text: "Make me a sandwich"},
             {id: 3, replyTo: 1, text: "hello back"},
             {id: 4, replyTo: 2, text: "no chance"},
             {id: 5, replyTo: 1, text: "who are you?"},
             {id: 6, replyTo: 5, text: "me of course"},
             {id: 7, replyTo: 0, text: "new question"},
             {id: 8, replyTo: 7, text: "new answer"}];

var convoSorted = [];

function addToReplies(obj, rply){ //recursive function to find the q. to reply to.
  if (obj.id == rply.replyTo){
    obj.replies.push({id: rply.id, text: rply.text, replies: []}); //add to the replies array
  }
  else{
      for (k = 0; k < obj.replies.length; k++){
        addToReplies(obj.replies[k], rply);
      }
  }
}

function sortConvo(){

  for (i = 0; i < convo.length; i++){
    if (convo[i].replyTo == 0){ //if it's not a reply, add to sorted array
      convoSorted.push({ id : convo[i].id, text: convo[i].text, replies: [] });
    }
    else{ //it's a reply, find the question it's replying
      for (j = 0; j < convoSorted.length; j++){
          addToReplies(convoSorted[j], convo[i]);
      }
    }
  }
}

sortConvo();
console.log(convoSorted);
var-conva=[{id:1,replyTo:0,文本:“hello world”},
{id:2,回复:0,文本:“给我做个三明治”},
{id:3,回复:1,文本:“hello back”},
{id:4,答复:2,案文:“没有机会”},
{id:5,回复:1,文本:“你是谁?”},
{id:6,答复:5,正文:“当然是我”},
{id:7,答复:0,文本:“新问题”},
{id:8,答复:7,案文:“新的答复”}];
var=[];
函数addToReplies(obj,rply){//递归函数,用于查找要回复的q。
if(obj.id==rply.replyTo){
obj.replays.push({id:rply.id,text:rply.text,replays:[]});//添加到replays数组
}
否则{
对于(k=0;k
我觉得自己是个白痴——我把事情复杂化了

它所需要的只是一点横向思考(这一讨论有助于)

msgs=[
{id:1,回复:0,msg:'Hello World'},
{id:2,回复:0,msg:'给我做个三明治'},
{id:3,回复:1,消息:'Hello back'},
{id:4,回复:2,消息:'No chance'},
{id:5,回复:1,消息:'你是谁?'},
{id:6,回复:5,msg:'当然是我'}
];
msgs.sort(函数(a,b){
返回a.reply-b.reply;
});
变量对话=$(“”);
变量列表=$(“
    ”) .attr(“id”、“线程”+msgs[0]。回复); 变量消息=$(“
  • ”) .text(msgs[0].msg) .attr(“id”、“msg_u3;”+msgs[0].id); $(列表)。附加(消息); $(对话).append(列表);
    对于(i=1;iYou可能会发现这一点很有帮助:。Postgres支持CTE,这使得这一点更加容易。不确定您是否阅读了“回复到”。如果仍然需要收集数据,为什么不使用“线程”如中所示。由于没有关于应用程序上下文的更多上下文可用,这似乎使生活变得更加轻松。抱歉@Abecee总是很难决定要包含多少信息而不会变得过于冗长-在这种情况下,我无法控制数据结构-我被我喜欢的字段所困扰-我正在尝试这样做在目前的排序功能中——我相信我离一些真正优雅的逻辑只有一步之遥:)@PerryW让我们知道你的想法。我很好奇它是如何作为一个排序功能来实现的。Hi@artm我很接近(见原始问题中的编辑),但后来有了我在自己的答案中发布的尤里卡时刻-因为这最终成为了一个网页,所以简单地将DOM用作一个归档系统要容易得多,这根本不是一个排序问题,这很好。。。我承认现在我的头受了伤,但很可能就是这样
    msgs=[
      {id:1,reply:0,msg:'Hello World'},
      {id:2,reply:0,msg:'Make me a sandwich'},
      {id:3,reply:1,msg:'Hello back'},
      {id:4,reply:2,msg:'No chance'},
      {id:5,reply:1,msg:'Who are you?'},
      {id:6,reply:5,msg:'Me of course'}
    ];
    msgs.sort(function(a,b){
      return a.reply - b.reply;
    });
    
    var conversation=$("<div id='threaded'>");
    var list = $("<ul>")
      .attr("id","thread_" + msgs[0].reply);
    var message = $("<li>")
      .text(msgs[0].msg)
      .attr("id","msg_" + msgs[0].id);
    $(list).append(message);
    $(conversation).append(list);
    
    for (i=1; i<msgs.length; i++){
      var message = $("<li>")
        .text(msgs[i].msg)
        .attr("id","msg_" + msgs[i].id);
      if ($(conversation).find("#msg_" + msgs[i].reply).length == 0){
        $(conversation).find("ul:eq(0)").append(message);
      } else {
        var list = $("<ul>")
          .attr("id","thread_" + msgs[i].id);
        $(list).append(message);
        $(conversation).find("#msg_" + msgs[i].reply).append(list);
      }
    }