JavaScript:数组操作

3

我正在使用React JS制作聊天应用,以下是我的一个对象数组:

const messages = [ 
  {message: "ghhhhhhhh", receiver: "faty", sender: "harry", time: "10/1/2019 12:56"},
  {message: "ggggggghjjgcgh", receiver: "harry", sender: "marie", time: " 10/1/2019 12:45"},
  {message: "good afternoon", receiver: "harry", sender: "marie", time: " 10/1/2019 12:41"},
  {message: "hfdsghfdfhjo", receiver: "faty", sender: "harry", time: " 10/1/2019 12:38"},
  {message: "hhhhhhhhhhhhh ", receiver: "harry", sender: "faty", time: " 10/1/2019 11:50"}
];

我想展示每个人之间的最后一条消息。
我尝试了下面的代码,但它没有呈现出我想要的结果。
    const senders =messages.reduce((a, c) => {
      a[c.sender] = a[c.sender] || { data: [] };
      a[c.sender].data.push({ sender: c.sender, message: c.message, time: c.time, receiver: c.receiver, hotel_id: c.hotel_id, isseen: c.isseen });
      a[c.sender].data.sort((a, b) =>{console.log(new Date(b.time),'aaaaaaaaaaaaaa');return ( new Date(b.time).getTime() - new Date(a.time).getTime())})
      return a;
    }, {})
    var messageInbox = Object.values(senders).map(s => s.data[0])
    console.log("Latest messages:", messageInbox);

这是我想要展示的内容:

  {message: "ghhhhhhhh", receiver: "faty", sender: "harry", time: "10/1/2019 12:56"},
  {message: "ggggggghjjgcgh", receiver: "harry", sender: "marie", time: " 10/1/2019 12:45"}

让我解释一下,我有两个人Faty和Harry,他们之间有很多对话信息。我想要显示他们之间的最后一条消息,同时也想要显示Harry和Marie之间的最后一条消息。

如果你理解我的问题,请帮助我,谢谢。


1
请提供期望的输出。 - Belmin Bedak
@BelminBedak 好的 - ch mariem
@BelminBedak 我已经解释了,请查看问题。 - ch mariem
听起来你有三个人,包括“玛丽”。 - Dexygen
@Dexygen 是的,我想要显示哈利和法蒂之间的消息/哈利和玛丽之间的消息。 - ch mariem
5个回答

1
如果您不在乎一对收件人是发件人还是接收者(因此Hary可以是接收者/发送者,而Faty则相反) - 根据您的期望输出,似乎您并不在乎 - 那么下面的代码应该可以工作。首先,我按时间顺序对消息进行排序,因为这样在使用reduce迭代时,第一个唯一的收件人组合将是它们之间的最后一条消息。
然后,我为收件人对创建唯一键,无论他们是接收方还是发送方,都将它们添加到数组中,对该数组进行排序,并进行JSON字符串化。排序是使您将获得收件人之间的最后一条消息的原因,而不管谁是接收者,谁是发送者 - 如果您想要Hary和Faty的两个条目,每个条目都有一个接收者或发送者,则删除排序。
如果我在reduce的每次迭代中返回的对象尚未具有该键,则使用该键添加消息;如果它已经具有该条目,则跳过它,因为我们已经拥有了该特定收件人对的最后一条消息。最后,我在reduce返回的对象上调用Object.values。

这段代码也在此repl中:https://repl.it/@dexygen/lastMessagesBetweenRecipientPairs

messages.sort((a,b)=>{new Date(b.time) - new Date(a.time)}); // reverse time order

const lastMessagesBetweenRecipientPairs = messages.reduce((lastMessages, msg) => {
    let key = JSON.stringify([msg.sender, msg.receiver].sort());
    if (!lastMessages[key]) lastMessages[key] = msg;
    return lastMessages;
}, {});

console.log(Object.values(lastMessagesBetweenRecipientPairs));

输出:
[ { message: 'ghhhhhhhh',
    receiver: 'faty',
    sender: 'harry',
    time: '10/1/2019 12:56' },
  { message: 'ggggggghjjgcgh',
    receiver: 'harry',
    sender: 'marie',
    time: ' 10/1/2019 12:45' } ]

0

您可以通过简单的操作实现目标:

  • 您可以使用reduce方法按多个键(例如receiversender)进行分组
  • 在数据分组后,您可以通过time属性对messages进行sort。代码如下:s.messages.sort((a, b) => new Date(b.time) - new Date(a.time))
  • 然后,您只需获取messages数组的第一个项目。代码如下:...s.messages.sort((a, b) => new Date(b.time) - new Date(a.time))[0] || ''

因此,整个代码可能如下所示:

let result = [...messages.reduce((r, o) => {    
  const key = o.receiver + '-' + o.sender;    
  const item = r.get(key) || Object.assign({}, o, {
    messages: []
  });    
  item.messages.push({message: o.message, time: o.time});    
  return r.set(key, item);
}, new Map).values()];

result = result.map( s=> ({receiver: s.receiver, sender: s.sender, 
    ...s.messages.sort((a, b) => new Date(b.time) - new Date(a.time))[0] || '' }))

一个例子:

const messages = [ 
  {message: "ghhhhhhhh", receiver: "faty", sender: "harry", time: "10/1/2019 12:56"},
  {message: "ggggggghjjgcgh", receiver: "harry", sender: "marie", time: " 10/1/2019 12:45"},
  {message: "good afternoon", receiver: "harry", sender: "marie", time: " 10/1/2019 12:41"},
  {message: "hfdsghfdfhjo", receiver: "faty", sender: "harry", time: " 10/1/2019 12:38"},
  {message: "hhhhhhhhhhhhh ", receiver: "harry", sender: "faty", time: " 10/1/2019 11:50"}
];

let result = [...messages.reduce((r, o) => {
  const key = o.receiver + '-' + o.sender;
  const item = r.get(key) || Object.assign({}, o, {
    messages: []
  });
  item.messages.push({message: o.message, time: o.time});
  return r.set(key, item);
}, new Map).values()];

result = result.map( s=> ({receiver: s.receiver, sender: s.sender, 
    ...s.messages.sort((a, b) => new Date(b.time) - new Date(a.time))[0] || '' }))
console.log(result);


不是我的投票,但我猜可能是因为:1.答案没有产生请求的结果,2.你没有解释任何东西。你只是提供了一个片段来满足OP的需求。3.那不是好的、自我解释的代码;对于一些新手来说,这肯定只是胡言乱语。而且单个字符的变量名可能在你随便写点什么时很快使用,但如果你或其他人以后要阅读这段代码,就不是这样了。也许这就是downvote的原因。 - Thomas
@Thomas 感谢您的精彩评论。我已经编辑了我的回答。在我看来,它变得更加清晰和完善了。 - StepUp

0

您可以使用以下代码

 const messages = [
                {message: "ghhhhhhhh", receiver: "faty", sender: "harry", time: "10/1/2019 12:56"},
                {message: "ggggggghjjgcgh", receiver: "harry", sender: "marie", time: " 10/1/2019 12:45"},
                {message: "good afternoon", receiver: "harry", sender: "marie", time: " 10/1/2019 12:41"},
                {message: "hfdsghfdfhjo", receiver: "faty", sender: "harry", time: " 10/1/2019 12:38"},
                {message: "hhhhhhhhhhhhh ", receiver: "harry", sender: "faty", time: " 10/1/2019 11:50"}
            ];

            function groupBy(objectArray, property) {
                return objectArray.reduce(function (acc, obj) {
                    var key = obj[property];
                    if (!acc[key]) {
                        acc[key] = [];
                    }
                    acc[key].push(obj);
                    return acc;
                }, {});
            }
            var messages1 = groupBy(messages, 'receiver');
            console.log(messages1); // get it in array with key as (harray or marie)
            var message2 = [];
            for(var k in messages1) {
                message2.push(messages1[k][0]); (// push them in simple array)
            }

0

如果您需要每个组合的最新消息,这里有一个函数可以检查。您将获得最新的faty-to-harry,harry-to-faty和harry-to-marie。

 const getLatest = (messages) => {
  const hash = {};
  // Turns data into objects like this, to store which is latest:
  // {
  //   key: {
  //     time: timestamp,
  //     message: {}
  //   },
  // }

  for (let message of messages) {
    let sender = message.sender;
    let receiver = message.receiver;
    let time = message.time;

    let record = hash[`${sender}${receiver}`];
    if (record === undefined || new Date(record.time) > new Date(time)) {
      hash[`${sender}${receiver}`] = {};
      hash[`${sender}${receiver}`].time = time;
      hash[`${sender}${receiver}`].message = message;
    }
  }

  return Object.keys(hash).map(key => hash[key].message);
}

-1

按日期对元素进行排序,然后根据您想要的接收者或发送者进行过滤,并选择最后一个length-1索引:

  const lastMessage =
  messages[
    messages
      .sort((a, b) => {
        new Date(a.time) - new Date(b.time);
      })
      .filter(el => el.sender === "faty" && el.receiver === "harry").length - 1
  ];

看它如何运作:

const messages = [ 
  {message: "ghhhhhhhh", receiver: "faty", sender: "harry", time: "10/1/2019 12:56"},
  {message: "ggggggghjjgcgh", receiver: "harry", sender: "marie", time: " 10/1/2019 12:45"},
  {message: "good afternoon", receiver: "harry", sender: "marie", time: " 10/1/2019 12:41"},
  {message: "hfdsghfdfhjo", receiver: "faty", sender: "harry", time: " 10/1/2019 12:38"},
  {message: "hhhhhhhhhhhhh ", receiver: "harry", sender: "faty", time: " 10/1/2019 11:50"}
];


const lastMessage =
  messages[
    messages
      .sort((a, b) => {
        new Date(a.time) - new Date(b.time);
      })
      .filter(el => el.sender === "faty" && el.receiver === "harry").length - 1
  ];

console.log(lastMessage)


谢谢你的回复,但是你还没有理解我的问题。 - ch mariem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接