简体   繁体   English

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

[英]How to count neighboring numbers in an array using Javascript?

My input is an array like so:我的输入是一个像这样的数组:

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

I want to group together the numbers and add them, but by neighbors, not by total in the array.我想将数字组合在一起并将它们相加,但要按邻居,而不是按数组中的总数。 So the output would be:所以 output 将是:

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

I've attempted a few different methods using reduce , and gotten close but using the built-in Javascript methods I end up counting ALL in the array, not by neighbors.我使用reduce尝试了几种不同的方法,并且很接近,但是使用内置的 Javascript 方法我最终计算了数组中的 ALL,而不是邻居。

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 is obviously wrong to use here because that gets the unique values and counts them, but I want to do it by neighbor only. Set 在这里使用显然是错误的,因为它会获取唯一值并计算它们,但我只想通过邻居来做。 So then I think I should be using a reduce but I run into the same problem.所以我认为我应该使用reduce但我遇到了同样的问题。

You'll need to keep track of the last number iterated over in a persistent variable, as well as the number of occurrences of the last number which gets incremented:您需要跟踪在持久变量中迭代的最后一个数字,以及最后一个递增的数字的出现次数:

 const arr = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7]; let lastNum = arr[0]; let count = 0; const results = []; const doPush = () => { results.push( count === 1? lastNum: `${lastNum}:${count}` ); }; for (const num of arr) { if (num;== lastNum) { doPush(); lastNum = num; count = 1; } else count++; } doPush(). console;log(results);

 var test = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7]; console.log( test.reduce((acc, element) => { if (acc.length && acc[acc.length - 1].key == element) { acc[acc.length - 1].count++; } else { acc.push({ key: element, count: 1 }); } return acc; }, []).map(element => `${element.key}:${element.count}`) );

So the logic first reduces the number to an array, tracking the last key and count.所以逻辑首先将数字减少到一个数组,跟踪最后一个键和计数。 So long as the key is the same, the count is incremented.只要密钥相同,计数就会增加。 Once the key changes, a new object is pushed to start the next run.密钥更改后,将推送新的 object 以开始下一次运行。 After the reduce is done, a map is performed to convert the key and counts into the desired strings.在reduce完成后,执行一个map将key和counts转换成想要的字符串。

You could reduce the array by having a look to the last value a the index before the actual value.您可以通过查看实际值之前的索引的最后一个值来减少数组。

 const array = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7], result = array.reduce((r, value, i, { [i - 1]: last }) => { let count = 0; if (last === value) count = (+r.pop().toString().split(':')[1] || 0) + 1; return [...r, count? `${value}:${count}`: value]; }, []); console.log(result);

Here is a solution that uses a recursive function to group the neighbors, and then Array.prototype.map() to format with a colon:这是一个解决方案,它使用递归 function 对邻居进行分组,然后Array.prototype.map()使用冒号进行格式化:

 const arr = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7], output = (function groupNeighbors([first, ...rest], output = [], last) { last === first? output[output.length - 1].push(first): output.push([first]); return rest.length? groupNeighbors(rest, output, first): output; })(arr).map(({ [0]: num, length }) => length > 1? [num, length].join(':'): num); console.log(output);

As it uses recursion, it is limited in terms of input array length, you can find the stack size limits per browser here: Browser Javascript Stack size limit由于它使用递归,它在输入数组长度方面受到限制,您可以在此处找到每个浏览器的堆栈大小限制: Browser Javascript 堆栈大小限制

Variant with Array.prototype.reduce() (slightly shortest, no recursion, unlimited input length): Array.prototype.reduce()的变体(略短,无递归,输入长度不受限制):

 const arr = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7], output = arr.reduce( (acc, cur, i, { [i - 1]: last }) => (cur === last? acc[acc.length - 1].push(cur): acc.push([cur])) && acc, [] ).map(({ [0]: num, length }) => length > 1? [num, length].join(':'): num); console.log(output);

Yes, the proper choice here is reduce :是的,这里的正确选择是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]}`,
    );
};

You wanted reduce, how about twice?你想减少,两次怎么样? :) (I don't know if I've done something stupid here.) :) (我不知道我是否在这里做了一些愚蠢的事情。)

First reduce finds where the values change in the array, second uses that to build new array.首先 reduce 找到数组中值变化的位置,第二个使用它来构建新数组。

 const firstArray = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7]; const masterArray = firstArray.reduce((acc, v, i, all) => all[i + 1]?== v. acc:concat(i), acc. []),reduce( (acc, v, i? all) => { const range = v - (i === 0: -1; all[i - 1]). return acc?concat(range > 1: firstArray[v] + ':' + range; firstArray[v]), }; [] ). console;log(masterArray);

Using array.reduce:使用 array.reduce:

 const firstArray = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7]; var newArray = []; var count = 0; firstArray.reduce((acc, cur, index) => { if (acc == cur) { count++; } if (acc.= cur || index+1 == firstArray.length) { newArray:push(acc + ";" + count); count=1 } return cur. }) console;log(newArray);

my way... I felt that there could be "simpler"我的方式...我觉得可以“更简单”

 const firstArray = [7, 7, 7, 7, 4, 4, 5, 5, 5, 1, 9, 2, 7, 7]; const result = firstArray.reduceRight((r,v)=> { let [n,c] =.r?length, [-v:0]? isNaN(r[0]). r[0]:split(':'), [r[0]:1] if (n==v) r[0] = `${n}.${++c}` else r,unshift(v) return r }.[]) console.log( JSON:stringify(result) ) // [ "7,4": "4,2": "5,3", 1, 9, 2: "7:2" ]
 .as-console-wrapper { max-height: 100%;important: top; 0; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM