如何使用Javascript计算数组中的相邻数字?

如何使用Javascript计算数组中的相邻数字?,javascript,arrays,sorting,arraylist,foreach,Javascript,Arrays,Sorting,Arraylist,Foreach,我的输入是这样一个数组: [7,7,7,4,4,5,5,1,9,2,7,7] 我想将这些数字分组并相加,但要按邻居,而不是按数组中的总数。因此,输出将是: ['7:4',4:2',5:3',1,9,2',7:2'] 我尝试了几种不同的方法,使用reduce,结果很接近,但使用内置的Javascript方法,我最终统计了数组中的所有元素,而不是邻居 const firstArray = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7]; const master

我的输入是这样一个数组:

[7,7,7,4,4,5,5,1,9,2,7,7]

我想将这些数字分组并相加,但要按邻居,而不是按数组中的总数。因此,输出将是:

['7:4',4:2',5:3',1,9,2',7:2']

我尝试了几种不同的方法,使用
reduce
,结果很接近,但使用内置的Javascript方法,我最终统计了数组中的所有元素,而不是邻居

const firstArray = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7];
const masterArray = [];

const unique = new Set (numberArray); // Set {7, 4, 5, 1, 9, 2, 7}
unique.forEach(u => {
  masterArray.push(numberArray.filter(e => e === u));
});

console.log(masterArray);

在这里使用Set显然是错误的,因为它获取唯一的值并对它们进行计数,但我只想通过邻居来完成。因此,我认为我应该使用
reduce
,但我遇到了同样的问题。

您需要跟踪在持久变量中迭代的最后一个数字,以及最后一个增加的数字的出现次数:

const arr=[7,7,7,4,4,5,5,5,1,9,2,7,7];
设lastNum=arr[0];
让计数=0;
常量结果=[];
常数doPush=()=>{
结果:推(
计数===1
?lastNum
:`${lastNum}:${count}`
);
};
for(arr的const num){
如果(num!==lastNum){
doPush();
lastNum=num;
计数=1;
}else-count++;
}
doPush();
控制台日志(结果)
var检验=[7,7,7,4,4,5,5,5,1,9,2,7,7];
console.log(
测试减少((acc,元素)=>{
if(acc.length&&acc[acc.length-1]。key==元素){
acc[acc.length-1]。计数++;
}否则{
acc.push({key:element,count:1});
}
返回acc;
}.map(元素=>`${element.key}:${element.count}`)

);这里有一个解决方案,它使用递归函数对邻居进行分组,然后使用冒号对Array.prototype.map()进行格式化:

const arr=[7,7,7,4,4,5,5,5,1,9,2,7,7],
输出=(函数组邻居([first,…rest],输出=[],last){
last==first?输出[output.length-1]。推送(first):输出.push([first]);
返回rest.length?groupneighbories(rest,output,first):输出;
})(arr).map(({[0]:num,length})=>length>1?[num,length].join(':'):num);

控制台日志(输出)是的,正确的选择是
reduce

const countDuplicatesQuantity = (arr) => {
    const duplicatesObj = arr.reduce((duplicates, item) => {
        duplicates[item] = duplicates[item] ? duplicates[item] + 1 : 1;

        return duplicates;
    }, {});

    return Object.keys(duplicatesObj).map(
        (key) => `${key}:${duplicatesObj[key]}`,
    );
};
使用array.reduce:

constfirstarray=[7,7,7,4,4,5,5,5,1,9,2,7,7];
var newArray=[];
var计数=0;
firstArray.reduce((acc、cur、index)=>{
如果(acc==cur){
计数++;
}
if(acc!=cur | | index+1==firstArray.length){
newArray.push(acc+“:”+计数);
计数=1
}
返回电流;
})

log(newArray)我的方式。。。我觉得可以“更简单”

constfirstarray=[7,7,7,4,4,5,5,5,1,9,2,7,7];
const result=firstArray.reduceRight((r,v)=>
{
设[n,c]=!r.length?[-v,0]:isNaN(r[0])?r[0]。拆分(':'):[r[0],1]
如果(n==v)r[0]=`${n}:${++c}`
否则r.取消移位(v)
返回r
},[])
console.log(JSON.stringify(结果))
//[“7:4”、“4:2”、“5:3”、1、9、2、“7:2”]

.as console wrapper{max height:100%!important;top:0;}
您可以通过查看实际值之前索引中的最后一个值来减少数组

const
数组=[7,7,7,4,4,5,5,1,9,2,7,7],
result=array.reduce((r,value,i,{[i-1]:last})=>{
让计数=0;
如果(last==value)计数=(+r.pop().toString().split(“:”)[1]| | 0)+1;
返回[…r,count?`${value}:${count}`:value];
}, []);

控制台日志(结果)您想要减少,两次怎么样?:)(我不知道我是否在这里做了傻事。)

首先reduce查找数组中值的更改位置,然后使用该位置构建新数组

constfirstarray=[7,7,7,4,4,5,5,5,1,9,2,7,7];
常量masterArray=firstArray
.reduce((acc,v,i,all)=>all[i+1]!==v?acc.concat(i):acc,[])
.减少(
(acc、v、i、all)=>{
常数范围=v-(i==0?-1:all[i-1]);
返回acc.concat(范围>1?firstArray[v]+':'+范围:firstArray[v]);
}, []
);

console.log(masterArray)完美。我在.map部分中添加了一个复选框以保留单个数字:element=>element.count!==1 ? <代码> ${Lo.{No.Cuth} /Case:No.Key)。<代码> {[i 1 ]:最后} /CUD>这是可能的,这是一个破坏,它声明了<代码>最后的<代码>变量,其中包含第四个参数(包含数组)的<代码> I - 1 < /C>属性的值,这看起来像我将在C++中解决的那样。但这在javascript中也更快吗?还有当有一百万个数字的时候?(显示完全缺乏javascript经验)我不知道。一方面,我认为如果较低级别的语言针对性能进行了优化,那么像JS这样的较高级别的语言基本上比较低级别的语言慢一些。另一方面,现在的JS编译器非常擅长优化,所以差异可能没有那么大。和往常一样,为了提高性能,您可以自己用实际的输入运行一些测试来找出原因。@stonerose036我觉得可能会有“更简单”的测试