【问题标题】:Group same elements in JS array, but only when consecutive将JS数组中的相同元素分组,但仅在连续时
【发布时间】:2018-11-18 17:35:51
【问题描述】:

我有一组对象,代表聊天中的一系列“消息”。我想对存储在每个数组项中的相同“用户”连续创建的消息进行分组。这是我正在尝试做的简化版本:

[
    { message: "One", user: "Bob" },
    { message: "Two", user: "Bob" },
    { message: "Three", user: "Bob" },
    { message: "Hello", user: "Sam" },
    { message: "Hello", user: "Bob" },
    { message: "Hello", user: "Sam" },
    { message: "Hello", user: "Sam" }
]

应该变成:

[
    [
        { message: "One", user: "Bob"},
        { message: "Two", user: "Bob" },
        { message: "Three", user: "Bob" }
    ],
    [
        { message: "Hello", user: "Sam" }
    ],
    [
        { message: "Hello", user: "Bob" }
    ],
    [
        { message: "Hello", user: "Sam" },
        { message: "Hello", user: "Sam" }
    ]
]

有什么简单的方法可以做到这一点吗?我在任何地方都找不到答案/算法。

【问题讨论】:

    标签: javascript arrays grouping


    【解决方案1】:

    您可以使用reduce 方法来做到这一点。

    const data = [
      { message: "One", user: "Bob" },
      { message: "Two", user: "Bob" },
      { message: "Three", user: "Bob" },
      { message: "Hello", user: "Sam" },
      { message: "Hello", user: "Bob" },
      { message: "Hello", user: "Sam" },
      { message: "Hello", user: "Sam" }
    ];
    
    const result = data.reduce((acc, value) => {
      // compare the current value with the last item in the collected array
      if (acc.length && acc[acc.length - 1][0].user == value.user) {
        // append the current value to it if it is matching
        acc[acc.length - 1].push(value);
      } else {
        // append the new value at the end of the collected array
        acc.push([value]);
      }
    
      return acc;
    }, []);
      
    console.log(result);

    【讨论】:

      【解决方案2】:

      你可以这样做:

      const messages = [
          { message: "One", user: "Bob" },
          { message: "Two", user: "Bob" },
          { message: "Three", user: "Bob" },
          { message: "Hello", user: "Sam" },
          { message: "Hello", user: "Bob" },
          { message: "Hello", user: "Sam" },
          { message: "Hello", user: "Sam" }
      ]
      
      let currentUser;
      let groupedMessages = [];
      
      for (message of messages) {
      
        if (message.user !== currentUser) {
          groupedMessages.push([]);
          currentUser = message.user;
        }
        groupedMessages[groupedMessages.length - 1].push(message)
      }
      
      console.log(groupedMessages);

      【讨论】:

        【解决方案3】:

        您可以检查最后一个元素,如果它没有相同的用户,则创建一个新数组。

        var data = [{ message: "One", user: "Bob" }, { message: "Two", user: "Bob" }, { message: "Three", user: "Bob" }, { message: "Hello", user: "Sam" }, { message: "Hello", user: "Bob" }, { message: "Hello", user: "Sam" }, { message: "Hello", user: "Sam" }],
            grouped = data.reduce((r, o, i, a) => {
                if (!i || a[i - 1].user !== o.user) {
                    r.push([]);
                }
                r[r.length - 1].push(o);
                return r;
            }, []);
            
        console.log(grouped);

        【讨论】:

          【解决方案4】:

          您可以只使用Array.reduce 并使用数组的indexactual array 的参数来解决这个问题:

          const data = [{ message: "One", user: "Bob" }, { message: "Two", user: "Bob" }, { message: "Three", user: "Bob" }, { message: "Hello", user: "Sam" }, { message: "Hello", user: "Bob" }, { message: "Hello", user: "Sam" }, { message: "Hello", user: "Sam" } ]
          
          const group = d => d.reduce((r,c,i,a) => (a[i].user == (a[i-1] && a[i-1].user) 
           ? r[r.length-1].push(c) : r.push([c]), r), [])
          
          console.log(Object.values(group(data)))

          【讨论】:

            猜你喜欢
            • 2011-06-13
            • 2023-03-07
            • 1970-01-01
            • 2017-03-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-12
            • 1970-01-01
            相关资源
            最近更新 更多