【问题标题】:I would like to count matching neighboring items in an array and return the count我想计算数组中匹配的相邻项目并返回计数
【发布时间】:2026-01-18 17:35:01
【问题描述】:

我有一个数组,我想找到所有相邻的匹配项并对它们进行计数,然后返回计数,在 .map() 之类的循环中执行,因此无需存储超出当前计数的内存元素。我需要使用这个数量的当前元素为每组元素保留足够的空间

array = [ball, batter, batter, amount, amount, github, github, github, account, account, account, account, account, account, account, github, github, github]

此数组的期望结果示例如下:第一个循环将返回 1,第二个循环将返回 2,然后是 2,然后是 3,然后是 7,然后是 3

这个计数将用作保留空间的变量,例如

number to reserve: count

因此通过每个循环,变量count 将被更改并更新为当前元素计数,并且计数的循环不会停止,直到下一个元素与当前元素不匹配,并且变量@987654325在找到所有并发匹配之前,@ 也将无法使用,因此如果我将 console.log(count) 放在函数末尾,我将分别获得每个数字输出

【问题讨论】:

  • 你说的并发匹配是什么意思?我觉得你可以从你的问题中删除 concurrent 这个词。在计算中,concurrent 通常意味着与您尝试使用该词的方式完全不同的东西。您是说连续吗?
  • 你能解释一下你实际解决了什么问题
  • 我有一个空格,我需要知道每个单词需要多少空格,ball 需要保留一个空格。击球手需要预留两个空间。金额需要保留两个空格
  • 为什么不直接使用字典并在一个循环中计数。
  • 查看thread的答案

标签: javascript arrays loops sorting


【解决方案1】:

您可以轻松地将数组中的连续字符串计算为:

const array = ["ball", "batter", "batter", "amount", "amount", "github", "github", "github", "account", "account", "account", "account", "account", "account", "account", "github", "github", "github"]

const result = [];
let last = array[0], lastSameIndex = 0;
for (let i = 1; i < array.length; ++i) {
  if (array[i] !== last) {
    result.push(i - lastSameIndex);
    lastSameIndex = i;
    last = array[i];
  }
}
result.push(array.length - lastSameIndex);

console.log(result);

让我们声明一些初始值

last = array[0]last = "ball"lastSameIndex = 0

所以我们必须从索引1 开始,我们只需要考虑两个元素不相等的单一情况,即array[i] !== last。如果它们不相等,那么我们必须将相同元素的计数推到现在:

result.push(i - lastSameIndex);

现在,我们必须更新新的值和索引,即 last 元素,我们必须再次计算该元素。

lastSameIndex = i;
last = array[i];

到目前为止一切都很好,但我们还必须处理循环结束的情况,在这种情况下,我们必须将最后一个元素的计数从计数开始的位置,即last 开始或lastSameIndex 推到最后一个元素。

result.push(array.length - lastSameIndex);

Second solution

const array = [ "ball", "batter", "batter", "amount", "amount", "github", "github", "github", "account", "account", "account", "account", "account", "account", "account", "github", "github", "github"];

let lastStr = "",
  num = 0;
const result = array
  .map((s) => {
    if (lastStr !== s) {
      lastStr = s;
      num = num === 0 ? 1 : 0;
    }
    return num;
  })
  .join("")
  .match(/(\d)\1*/g)
  .map((s) => s.length);
  
console.log(result);

【讨论】:

  • 解释原理...
  • @decpk 太棒了!
  • @Breakingnotsobad 我试过了。请有一个循环并添加另一个解决方案。
  • 两种方法都很好,但第二种方法如果你直接使用正则表达式会更有效,就像我在回答中所做的那样!
【解决方案2】:

所以循环每一项,如果不等于最后一项,则推送1,否则将1添加到数组中的最后一个数字。

const items = ["ball", "batter", "batter", "amount", "amount", "github", "github", "github", "account", "account", "account", "account", "account", "account", "account", "github", "github", "github"]

const results = [];

items.forEach((item, i) => {
    if (items[i - 1] !== item) return results.push(1);

    const last = results.length - 1;
    results[last] = results[last] + 1;
});

console.log(results);

【讨论】:

  • 老兄,你的解决方案不是 OP 想要的。输出应该是[1, 2, 2, 3, 7, 3] 而不是[1, 2, 2, 6, 7]。你只是在数数。
  • 哎呀,你是对的!固定。
【解决方案3】:
  • 尝试将数组加入到由array.join(",")分隔的字符串中:ball,batter,batter,amount,amount,github,github,github
  • 使用 regex: /([a-z]+,)\1*/gi 匹配相同的重复词给出: ['ball,', 'batter,batter,', 'amount,amount,', 'github,github,github,...]
  • 使用s.split(',').length-1计算数组中每个字符串的字数

脚本:

array.join(",").match(/([a-z]+,)\1*/gi).map((s) => `${s.split(',').length-1}`);

结果: ['1', '2', '2', '3', '7', '2']

【讨论】:

  • 这不是这个答案link的解决方案@
  • AFAIT,但是这个解决方案效率不高,因为与直接字符串比较相比,正则表达式需要做更多的工作
  • 是的,它是一样的,但是在这里我们处理的不是字符,而是相同的想法!
  • 不幸的是,好像我们用for循环做的那样效率不高,单词不应该包含,逗号!
  • 是的,我同意,但这可以作为替代解决方案。很棒
最近更新 更多