使用Javascript将连续的元素分组在一起
Grouping consecutive elements together using Javascript
我有一个元素数组,像这样:
messages[i]
,其中messages[i]
仅对i
的某些值存在。例如,messages[0]
和messages[2]
可能存在,但messages[1]
不存在。
现在我想将具有连续索引的元素分组在一起,例如,如果存在消息的索引为:
2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 16, 17, 20
我想这样分组:
2, 3, 4, 5
8, 9
12, 13, 14, 15, 16, 17
20
使用Javascript实现这一目标的有效方法是什么?
编辑:for (i = 0; i < messages.length; i++) {
if (messages[i].from_user_id == current_user_id) {
// group the continuous messages together
} else {
//group these continuous messages together
}
}
您可以使用计数器变量,该变量必须递增,并且索引和连续元素之间的差值相同,将它们分组在临时数组中。如果两个连续的数组元素的差值不同,则必须将临时元素移到result
中,并且必须为临时数组分配一个新的数组对象。
var array = [2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 16, 17, 20];
var result = [], temp = [], difference;
for (var i = 0; i < array.length; i += 1) {
if (difference !== (array[i] - i)) {
if (difference !== undefined) {
result.push(temp);
temp = [];
}
difference = array[i] - i;
}
temp.push(array[i]);
}
if (temp.length) {
result.push(temp);
}
console.log(result);
# [ [ 2, 3, 4, 5 ], [ 8, 9 ], [ 12, 13, 14, 15, 16, 17 ], [ 20 ] ]
给定:
var data = [ undefined, undefined, 2, 3, 4, 5,
undefined,undefined, 8, 9,
undefined, undefined, 12, 13, 14, 15, 16, 17,
undefined, undefined, 20];
(或者几乎相等的数组,其中undefined
元素根本不存在,但定义的元素具有与上面相同的索引),reduce
调用将返回一个二维数组,其中每个顶层元素是原始数组的内容,按连续定义的项分组:
var r = data.reduce(function(a, b, i, v) {
if (b !== undefined) { // ignore undefined entries
if (v[i - 1] === undefined) { // if this is the start of a new run
a.push([]); // then create a new subarray
}
a[a.length - 1].push(b); // append current value to subarray
}
return a; // return state for next iteration
}, []); // initial top-level array
。[[ 2, 3, 4, 5], [8, 9], [12, 13, 14, 15, 16, 17], [20]]
.forEach
调用来编写,但我喜欢.reduce
,因为它不需要临时变量-所有状态都封装在函数参数中。
我会遍历列表,如果在messages[i]
找到元素,则将i
添加到min列表中。然后,一旦在messages[j]
处找不到元素,就把j
放到最大值列表中。
那么您将有两个列表(或者一个,如果您使用容器,我可能会这样做),其中包含组的开始和停止索引。
另一种方法是这样的。我使用了一个叫做lodash的库来操作数组。
基本上我是按升序对数组进行排序。然后对于每一次增量,我将当前元素存储到一个临时数组中如果数组的最后一个值与当前元素的值是顺序的,那么比较它们的最后一个值如果它们不是顺序的,我将临时数组的值压入结果数组中,以此类推。如果循环结束,我就把临时数组的值压入结果数组。
var _ = require('lodash');
var arr = [2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 16, 17, 20];
arr = _.sortBy(arr, function (o) {
return o;
});
var tmp = [];
var res = [];
for (var i = 0; i < arr.length; i++) {
if (tmp.length === 0) {
tmp.push(arr[i]);
}
else {
var lastEl = _.last(tmp);
if ((lastEl + 1) === arr[i]) {
tmp.push(arr[i]);
}
else {
res.push(tmp);
tmp = [];
tmp.push(arr[i]);
}
if (i === (arr.length - 1)) {
res.push(tmp);
tmp = [];
}
}
}
// Outputs: [ [ 2, 3, 4, 5 ], [ 8, 9 ], [ 12, 13, 14, 15, 16, 17 ], [ 20 ] ]
const cluster = (arr, tmp = [], result = []) =>
(result = arr.reduce((acc, c, i) =>
(!tmp.length || c === (arr[i-1]+1)
? (tmp.push(c), acc)
: (acc.push(tmp), tmp = [c], acc))
, []), tmp.length ? (result.push(tmp), result) : result)
console.log(cluster([2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 16, 17, 20]))
- 如何使该数据在所有元素中加载
- 带有填充属性的SVG矩形显示在包含元素的上方插入框阴影
- HighCharts长标题文本在某些元素上重叠
- 将依赖外部库的UMD模块与browserfy捆绑在一起
- 在select元素中显示highchart dashstyle(svg)
- 使用fullpagejs在固定元素上滚动
- PHP:同时循环元素粘在一起
- 是否可以将相同属性的元素与 querySelectorAll 组合在一起
- 如何将两个 html 元素绑定在一起,当第一个元素被删除时,第二个元素也从 DOM 中删除
- JQuery - 将所选元素添加在一起 - 组合子元素
- 如何将两个不相关的元素粘在一起
- 将字符串与数组变量混合在一起,为javascript中的元素分配id
- 将装饰为html元素的内容附加在一起;不起作用
- 如何使用jquery将两个元素关联/链接在一起
- 循环浏览一个元素组合在一起的jQuery对象
- 当用Javascript将字符串连接在一起以组成一个新的DOM元素时,它只接受第一个以空格分隔的值
- jQuery-如何将DOM元素和Javascript对象链接在一起
- 当某些对象必须避免配对在一起时,如何将一个数组的元素随机映射到另一个数组中的元素
- 什么's使用相同的事件处理程序将多个元素分别与不同的事件绑定在一起的优雅方式
- 使用Javascript将连续的元素分组在一起