admin管理员组

文章数量:1193391

I am attempting (unsuccessfully) to write JavaScript function LetterCount to count the consecutive letters in a string (and not the total number).

Ideally: LetterCount("eeeeeoooohhoooee") = [["e", 5],["o",3],["h",2],["o",3],["e",2]]

The following code attempts to count the number of consecutive letters in a string only when I already know what they are:

function LetterCount(str) {
for (var i=0; i<str.length;i++) {
    var arr1=[]; arr2=[]; arr3=[]; arr4=[]; arr5=[];
    var e=0; o=0; h=0; o2=0; e2=0;
    if(str[i]="e") {
        arr1 += "e";
        e++;
    }
    arr1.push(e);
    if(str[i]="o") {
        arr2 += "o";
        o++;
    }
    arr2.push(o);
    if(str[i]="h") {
        arr3 += "h";
        h++;
    }
    arr3.push(h);
    if(str[i]="o") {
        arr4 += "o";
        o2++;
    }
    arr4.push(o2);
    if(str[i]="e") {
        arr5 += "e";
        e2++;
    }
    arr5.push(e2);
}
return arr1.concat(arr2).concat(arr3).concat(arr4).concat(arr5);
}

In the code above, I need to first know what the letters in the string are, and how many of them are present, in what order.

INSTEAD: How do you write a function that will automatically recognize the letter themselves, and then return the count of consecutive letters. Would also be great if the answer is in the following format:

 LetterCount("eeeeeoooohhoooee") = [["e", 5],["o",3],["h",2],["o",3],["e",2]]

Any help is much appreciated!

I am attempting (unsuccessfully) to write JavaScript function LetterCount to count the consecutive letters in a string (and not the total number).

Ideally: LetterCount("eeeeeoooohhoooee") = [["e", 5],["o",3],["h",2],["o",3],["e",2]]

The following code attempts to count the number of consecutive letters in a string only when I already know what they are:

function LetterCount(str) {
for (var i=0; i<str.length;i++) {
    var arr1=[]; arr2=[]; arr3=[]; arr4=[]; arr5=[];
    var e=0; o=0; h=0; o2=0; e2=0;
    if(str[i]="e") {
        arr1 += "e";
        e++;
    }
    arr1.push(e);
    if(str[i]="o") {
        arr2 += "o";
        o++;
    }
    arr2.push(o);
    if(str[i]="h") {
        arr3 += "h";
        h++;
    }
    arr3.push(h);
    if(str[i]="o") {
        arr4 += "o";
        o2++;
    }
    arr4.push(o2);
    if(str[i]="e") {
        arr5 += "e";
        e2++;
    }
    arr5.push(e2);
}
return arr1.concat(arr2).concat(arr3).concat(arr4).concat(arr5);
}

In the code above, I need to first know what the letters in the string are, and how many of them are present, in what order.

INSTEAD: How do you write a function that will automatically recognize the letter themselves, and then return the count of consecutive letters. Would also be great if the answer is in the following format:

 LetterCount("eeeeeoooohhoooee") = [["e", 5],["o",3],["h",2],["o",3],["e",2]]

Any help is much appreciated!

Share Improve this question edited Feb 23, 2015 at 18:58 Henry asked Feb 22, 2015 at 3:15 HenryHenry 2792 gold badges4 silver badges13 bronze badges 0
Add a comment  | 

6 Answers 6

Reset to default 18

You can use a regular expression to match any letter followed by zero or more instances of the same letter.

rx=/([a-zA-Z])\1*/g;

Your example matches ["eeeee","oooo","hh","ooo","ee"].

Using map, return the initial letter and the number of occurrences in a new array for each index.

function letterCount(str) {
  var s = str.match(/([a-zA-Z])\1*/g) || [];
  return s.map(function(itm) {
    return [itm.charAt(0), itm.length];
  });
}

console.log(letterCount("eeeeeoooohhoooee"))

returned value: (Array)

[["e",5],["o",4],["h",2],["o",3],["e",2]]

NOTES:

  1. var s= str.match(/([a-zA-Z])\1/g)||[];*

returns an array of matches (repeated letters) or an empty array([]). Otherwise, if the string does not contain any letters an error would be thrown (from calling map on null).

  1. \1* is used to allow matching instances of a single letter with any or no sequential repetition. '\1+' would not match a single unrepeated letter.

  2. Array map expects a function and passes three arguments- the value at each index, the index number, and a reference to the entire array. In this case, only the value of each index is used, so we can ignore the other arguments.

Actually "fixed" ["o",3] to ["o",4] ;)

// node v0.10.31
// assert v1.3.0

var assert = require('assert');

function letterCount(str) {
    var i = 0,
        seq = 0,
        results = [];

    while (i < str.length) {
        var current = str[i],
            next = str[i + 1];

        if (typeof results[seq] === 'undefined') {
            results[seq] = [current, 0];
        }

        results[seq][1]++;

        if (current !== next) {
            seq++;
        }

        i++;
    }

    return results;
}

var actual = letterCount('eeeeeoooohhoooee');
var expected = [["e", 5],["o",4],["h",2],["o",3],["e",2]];

assert.deepEqual(actual, expected);

This is my answer:

function LetterCount(str) {
    var current, i = 0, l = str.length;
    var outputArr = [];
    while(i<l) {
        current = str.charAt(i);
        if(!i++ || outputArr[outputArr.length-1][0] !== current)
            outputArr[outputArr.length] = [current, 1];
        else outputArr[outputArr.length-1][1]++;
        }
    return outputArr;
    }

As a modification to kennebec's (awesome) answer, so that the anonymous function isn't declared each time the parent function is called. This is only to reference a better programming practice in comparison to pure simplicity (this is probably the most efficient method):

var letterCount = (function(){
    var r = /([A-z])\1*/g,
        f = function(itm){
        return [itm.charAt(0), itm.length];
        };
    return function letterCount(str){
        return str.match(r).map(f);
        };
    }());

I'd use a map keyed on the character to store the count of consecutive chars and then build the output structure at the end. I'm not sure I understand exactly what you mean by consecutive based on your example but you can tweak the logic to identify a consecutive number accordingly.

function LetterCount(str) {
  var counts = {};
  for (var i = 0, prevChar = null; i < str.length; i++) {
    var char = str.charAt(i);
    if(counts.hasOwnProperty(char) && char === prevChar) {
      counts[char] = counts[char] + 1;  
    } else if (!counts.hasOwnProperty(char)) {
      counts[char] = 0;
    }
    prevChar = char;
  }
  var res = [];
  for (var char in counts) {
    if (counts.hasOwnProperty(char)) {
      res.push([char,counts[char]);
    }
  }
  return res;
}
function LetterCount(text){
    arr = [];
    letter = text[0];
    counter = 0;
    for (c in text+' '){
        if (text[c] != letter){
            newArr = [letter, counter];
            arr.push(newArr);
            letter = text[c];
            counter = 0;
        }
        counter += 1;
    };
    return arr;
}

const string = 'acbbaeekzzkeee';

function letterCount(str) {
  return [...str].reduce((acc, letter, index) => {
    if (index === 0 || letter !== str[index - 1]) {
      acc.push([letter, 1]);
    } else {
      acc[acc.length - 1][1]++;
    }
    return acc;
  }, []);
}

const count = letterCount(string);
console.log(count);

  1. ...spread string into array
  2. Loop through it with reduce, which initial value is empty array
  3. if it is first letter or previous letter is not same as letter
  4. Make an array with [letter, 1] and push it into accumulator array (1 is initial count/value)
  5. else increment previous array's value in accumulator's array. Since previous array will have same letter as our current letter
  • So whenever we have new value (non-consecutively) we add an array into array.
  • Else we increment last array's value (it will be same letter)

本文标签: arraysJavaScript function to automatically count consecutive letters in a stringStack Overflow