want to get a count of repeated values on an array [duplicate] - javascript

This question already has answers here:
JavaScript function to automatically count consecutive letters in a string
(5 answers)
Closed 1 year ago.
I am a beginner in javascript, I want to get a count of repeated values on an array
I have a string "aaaaaabbbbbbbcccccccaa" and I want the output array be like ["a6", "b7", "c7", "a2"];
I tied but failed. Please help me out
Thanks In Advance :)
var a = "aaaaaabbbbbbbcccccccaa";
function aa(data){
var a = [];
var x = [];
//var b = data.split("")
// var b = data.split("").filter((val,key, arr)=>{
// //console.log(arr.indexOf(val) +" "+ key )
// return arr.indexOf(val) === key
// })
//console.log(b);
for(let i = 0; i<= data.length-1; i++){
for(let j = 0; j<= data.length-1; j++){
if(data[i] !== data[j] && x.indexOf(data[i]+""+j) <0){
x.push(data[i]+""+j);
a.push(data[i] +""+ j);
break;
}
}
}
console.log(x);
return a;
}
console.log(aa(a));

I'd use a regular expression to match repeated characters in the string, then map them to match[0] + match.length to get the concatenated substring for that portion:
const aa = data => data
.match(/(.)\1*/g)
.map(match => match[0] + match.length);
console.log(aa('aaaaaabbbbbbbcccccccaa'));
If you don't want to use a regular expression, don't use a nested loop like that from 0 to the string length - instead, count up repeated characters from inside the first loop, starting at the current i index and incrementing it:
function aa(data) {
const result = [];
for (let i = 0; i < data.length; i++) {
const char = data[i];
let matches = 1;
while (data[i + 1] === char) {
i++;
matches++;
}
result.push(char + matches);
}
return result;
}
console.log(aa('aaaaaabbbbbbbcccccccaa'));

Related

expand a string in JavaScript to display letter and how many times that letter appears

Write a function that accepts a string where letters are grouped together and returns new string with each letter followed by a count of the number of times it appears.
example : ('aeebbccd') should produce // 'a1e2b2c2d1'
function strExpand(str) {
let results = ""
for (let i = 0; i < str.length; i++) {
let charAt = str.charAt(i)
let count = 0
results += charAt
for (let j = 0; j < str.length; j++) {
if (str.charAt(j) === charAt) {
count++;
}
}
results += count;
}
return results;
}
with the input 'aeebbccd' I am getting 'a1e2e2b2b2c2c2d1' instead of 'a1e2b2c2d1'
This function is adding a number after each character, which is the number of times this character appears anywhere in the string. You could instead do it like this to get the result you want.
function strExpand(str) {
let output = "";
// Iterate through each character of the string, appending
// to the output string each time
for (let i = 0; i < str.length; i++) {
let count = 1;
// If the next character is the same, increase the count
// and increment the index in the string
while (str[i + 1] == str[i]) {
count++;
i++;
}
// Add the character and the count to the output string
output += str[i] + count;
}
return output;
}
For sake of completeness,
how about a Regex?
const pattern = /(.)\1*/g; // put a char that exists in a capture group, then see if it repeats directly after
const s = 'aeebbccd';
var result = '';
for (match of s.match(pattern)) {
let this_group = match;
let this_len = match.length;
result = result + this_group[0] + this_len; // get only the first letter from the group
}
console.log(result); // a1e2b2c2d1
This would to the job. edit: hah i see im late :D, but still nice functional way to solve that.
/**
* #param string to count
* #return string $characterA$count. ex. abbccc -> a1b2c3
*/
function toCharacterCountString(str) {
return Array.from(new Set(str).values())
.map(char => {
return `${char}${(str.match(new RegExp(char, "g")) || []).length}`;
}).join('');
}
console.log(toCharacterCountString('abbccc')); // a1b2c3
console.log(toCharacterCountString('aeebbccd')); // a1e2b2c2d1

Character with longest consecutive repetition

i think i have wirtten the correct code for the problem only one thing and it that i return the first longest sequence how can i alter that to return the last maximum sequence?
an example from codewars editor :
for input '00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'
Expected: ['c', 19], instead got: ['0', 19]
here is my code:
function longestRepetition(s) {
var count = 0;
var temp = s.charAt(0);
var arr = [];
for (var i = 0; i < s.length; i++) {
if (temp === s.charAt(i)) {
count++
temp = s.charAt(i)
}
else {
temp = s.charAt(i);
arr.push(count)
count = 1;
}
if(i==s.length-1)
arr.push(count);
}
if(arr.length>0)
{
var Max=arr[0]
for(var i=0;i<arr.length;i++)
{
if(Max<=arr[i])
Max=arr[i];
}
}
else var Max=0;
var mindex=arr.indexOf(Max);
return [s.charAt(mindex),Max]
}
I think this would be easier with a regular expression. Match any character, then backreference that character as many times as you can.
Then, you'll have an array of all the sequential sequences, eg ['000', 'aaaaa']. Map each string to its length and pass into Math.max, and you'll know how long the longest sequence is.
Lastly, filter the sequences by those which have that much length, and return the last item in the filtered array:
function longestRepetition(s) {
const repeatedChars = s.match(/(.)\1*/g);
const longestLength = Math.max(...repeatedChars.map(str => str.length));
const longestChars = repeatedChars.filter(str => str.length === longestLength);
return [longestChars.pop(), longestLength];
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
The issue in your code is that minindex is an index in your arr, but that index has nothing to do with s. So s.charAt(minindex) makes no sense. You should maintain for which character you had found the count. For instance you could push in arr both the count and the corresponding character (as a subarray with two values). Then the rest of your code would only need little modification to make it work.
Applying this idea to your code without changing anything else, we get this:
function longestRepetition(s) {
var count = 0;
var temp = s.charAt(0);
var arr = [];
for (var i = 0; i < s.length; i++) {
if (temp === s.charAt(i)) {
count++
temp = s.charAt(i) // Not necessary: was already equal
}
else {
arr.push([temp, count]); // <--- pair, BEFORE changing temp
temp = s.charAt(i);
count = 1;
}
if(i==s.length-1)
arr.push([temp, count]); // <---
}
if(arr.length>0)
{
var Max=arr[0]; // <-- Max is now a pair of char & count
for(var i=0;i<arr.length;i++)
{
if(Max[1]<arr[i][1]) // Comparison changed to just less-than
Max=arr[i];
}
}
else Max=[null, 0]; // Must be a pair here also
return Max; // Just return the pair
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
But you can do the same with less code:
function longestRepetition(s) {
let result = [null, 0]; // pair of character and count
for (var i = 0; i < s.length; null) {
let start = i++;
while (i < s.length && s[i] === s[start]) i++; // Find end of series
if (i - start > result[1]) result = [s[start], i - start];
}
return result;
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
The solution below answers the question with O(n) runtime:
function longestRepetition(s) {
let count = s.length > 0 ? 1 : 0
let char = s.length > 0 ? s[0] : ''
for (let string_i = 0; string_i < s.length - 1; string_i += 1) {
// keep track of current_char
let current_char = s[string_i]
let next_char = s[string_i + 1]
// while the next char is same as current_char
let tracker = 1
while (current_char === next_char) {
// add one to tracker
tracker += 1
string_i += 1
next_char = s[string_i + 1]
}
// if tracker greater than count
if (tracker > count) {
// returned char = current char
// count =tracker
count = tracker;
char = current_char;
}
}
return [char, count]
}
console.log(longestRepetition("bbbaaabaaaa"))//, ["a",4]

JavaScript: How to count repetitive letters in a string and output the numbers right after?

I am trying to display an output like this a3b2c4d3 for a string aaabbccccddd.
I tried the code below but didn't get the desired result.
var countLetters = "aaabbccccddd";
console.log("countLetters.length --->" + countLetters.length);
var countNumberLetter = 0;
var i;
var a;
for (i = 0; i < countLetters.length; i++) {
if (countLetters[i] == countLetters[i + 1]) {
countNumberLetter = countNumberLetter + 1;
}
}
console.log("countNumberLetter--------->" + countLetters[i] + countNumberLetter);
Use two loops. Use an outer while to loop the string. Whenever a new letter is encountered, use the for loop to increment count as the long as the letters belong to the same sequence. When done increment the outer counter (i) to get to the next letter:
var countLetters = "aaabbccccddd";
var result = '';
var i = 0;
while (i < countLetters.length) {
// iterate until current letter, and counted letter are not equal, increment count
for (var count = 1; countLetters[i] === countLetters[i + count]; count++) {}
// add current letter and count to string
result += countLetters[i] + count;
i += count; // increment outer counter - i
}
console.log(result);
Another solution that uses a String.match() with a regex to get an array of letter sequences. Then maps each sequence to letter + count, and joins them back to a string:
var countLetters = "aaabbccccddd";
var result = countLetters.match(/(\w)\1+/g) // match sequences of the same letter
.map((s) => s[0] + s.length) // map each sequence to letter with count
.join(''); // join back to a string
console.log(result);
var hashMap = {};
var countLetters = "aaabbccccddd";
countLetters.split("").forEach((letter) => {
if(!hashMap[letter]) {
hashMap[letter] = 0;
}
hashMap[letter] = hashMap[letter]+1;
})
var string ='';
for(var i in hashMap) {
var val = hashMap[i];
string += i + val;
}
console.log("countNumberLetter--------->",string);
const object = {};
const string = "aaabbccccddd";
// To iterate over string
for(let i = 0; i < string.length; i++){
// if the object has that alphabet just increment it
if(object.hasOwnProperty(string.charAt(i))){
++object[string.charAt(i)];
}else{
// else create a key to the new alphabet and give it a value 1
object[string.charAt(i)] = 1;
}
}
let finalString = "";
// To iterate over the object
for(let key in object){
finalString += key; // concatenate the key
finalString += object[key]; // concatenate the value
}
console.log(finalString);
My solution has two loops one to iterate over the string and store the alphabet and there count in an object ( you can use hashmap as well ).
The 2nd loop is to iterate over object so that we can make the desired string.

Splitting Numbers and adding them all - JavaScript

I have a function that returns the sum of all its digits For both POSITIVE and NEGATIVE numbers.
I used split method and converted it to string first and then used reduce to add them all. If the number is negative, the first digit should count as negative.
function sumDigits(num) {
var output = [],
sNum = num.toString();
for (var i = 0; i < sNum.length; i++) {
output.push(sNum[i]);
}
return output.reduce(function(total, item){
return Number(total) + Number(item);
});
}
var output = sumDigits(1148);
console.log(output); // --> MUST RETURN 14
var output2 = sumDigits(-316);
console.log(output2); // --> MUST RETURN 4
Instead of returning the sum, it returned 4592 -1264
Am I doing it right or do I need to use split function? Or is there any better way to do this?
Sorry newbie here.
I think you'll have to treat it as a string and check iterate over the string checking for a '-' and when you find one grab two characters and convert to an integer to push onto the array. Then loop over the array and sum them. Of course you could do that as you go and not bother pushing them on the array at all.
function sumDigits(num) {
num = num + '';
var output = [];
var tempNum;
var sum = 0;
for (var i = 0; i < num.length; i++) {
if (num[i] === '-') {
tempNum = num[i] + num[i + 1];
i++;
} else {
tempNum = num[i];
}
output.push(parseInt(tempNum, 10));
}
for (var j = 0; j < output.length; j++) {
sum = sum + output[j];
}
return sum;
}
var output = sumDigits(1148);
console.log(output); // --> MUST RETURN 14
var output2 = sumDigits(-316);
console.log(output2); // --> MUST RETURN 4

Showing unique characters in a string only once

I have a string with repeated letters. I want letters that are repeated more than once to show only once.
Example input: aaabbbccc
Expected output: abc
I've tried to create the code myself, but so far my function has the following problems:
if the letter doesn't repeat, it's not shown (it should be)
if it's repeated once, it's show only once (i.e. aa shows a - correct)
if it's repeated twice, shows all (i.e. aaa shows aaa - should be a)
if it's repeated 3 times, it shows 6 (if aaaa it shows aaaaaa - should be a)
function unique_char(string) {
var unique = '';
var count = 0;
for (var i = 0; i < string.length; i++) {
for (var j = i+1; j < string.length; j++) {
if (string[i] == string[j]) {
count++;
unique += string[i];
}
}
}
return unique;
}
document.write(unique_char('aaabbbccc'));
The function must be with loop inside a loop; that's why the second for is inside the first.
Fill a Set with the characters and concatenate its unique entries:
function unique(str) {
return String.prototype.concat.call(...new Set(str));
}
console.log(unique('abc')); // "abc"
console.log(unique('abcabc')); // "abc"
Convert it to an array first, then use Josh Mc’s answer at How to get unique values in an array, and rejoin, like so:
var nonUnique = "ababdefegg";
var unique = Array.from(nonUnique).filter(function(item, i, ar){ return ar.indexOf(item) === i; }).join('');
All in one line. :-)
Too late may be but still my version of answer to this post:
function extractUniqCharacters(str){
var temp = {};
for(var oindex=0;oindex<str.length;oindex++){
temp[str.charAt(oindex)] = 0; //Assign any value
}
return Object.keys(temp).join("");
}
You can use a regular expression with a custom replacement function:
function unique_char(string) {
return string.replace(/(.)\1*/g, function(sequence, char) {
if (sequence.length == 1) // if the letter doesn't repeat
return ""; // its not shown
if (sequence.length == 2) // if its repeated once
return char; // its show only once (if aa shows a)
if (sequence.length == 3) // if its repeated twice
return sequence; // shows all(if aaa shows aaa)
if (sequence.length == 4) // if its repeated 3 times
return Array(7).join(char); // it shows 6( if aaaa shows aaaaaa)
// else ???
return sequence;
});
}
Using lodash:
_.uniq('aaabbbccc').join(''); // gives 'abc'
Per the actual question: "if the letter doesn't repeat its not shown"
function unique_char(str)
{
var obj = new Object();
for (var i = 0; i < str.length; i++)
{
var chr = str[i];
if (chr in obj)
{
obj[chr] += 1;
}
else
{
obj[chr] = 1;
}
}
var multiples = [];
for (key in obj)
{
// Remove this test if you just want unique chars
// But still keep the multiples.push(key)
if (obj[key] > 1)
{
multiples.push(key);
}
}
return multiples.join("");
}
var str = "aaabbbccc";
document.write(unique_char(str));
Your problem is that you are adding to unique every time you find the character in string. Really you should probably do something like this (since you specified the answer must be a nested for loop):
function unique_char(string){
var str_length=string.length;
var unique='';
for(var i=0; i<str_length; i++){
var foundIt = false;
for(var j=0; j<unique.length; j++){
if(string[i]==unique[j]){
foundIt = true;
break;
}
}
if(!foundIt){
unique+=string[i];
}
}
return unique;
}
document.write( unique_char('aaabbbccc'))
In this we only add the character found in string to unique if it isn't already there. This is really not an efficient way to do this at all ... but based on your requirements it should work.
I can't run this since I don't have anything handy to run JavaScript in ... but the theory in this method should work.
Try this if duplicate characters have to be displayed once, i.e.,
for i/p: aaabbbccc o/p: abc
var str="aaabbbccc";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 ){
return obj;
}
}
).join("");
//output: "abc"
And try this if only unique characters(String Bombarding Algo) have to be displayed, add another "and" condition to remove the characters which came more than once and display only unique characters, i.e.,
for i/p: aabbbkaha o/p: kh
var str="aabbbkaha";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 && str.lastIndexOf(obj,i-1)==-1){ // another and condition
return obj;
}
}
).join("");
//output: "kh"
<script>
uniqueString = "";
alert("Displays the number of a specific character in user entered string and then finds the number of unique characters:");
function countChar(testString, lookFor) {
var charCounter = 0;
document.write("Looking at this string:<br>");
for (pos = 0; pos < testString.length; pos++) {
if (testString.charAt(pos) == lookFor) {
charCounter += 1;
document.write("<B>" + lookFor + "</B>");
} else
document.write(testString.charAt(pos));
}
document.write("<br><br>");
return charCounter;
}
function findNumberOfUniqueChar(testString) {
var numChar = 0,
uniqueChar = 0;
for (pos = 0; pos < testString.length; pos++) {
var newLookFor = "";
for (pos2 = 0; pos2 <= pos; pos2++) {
if (testString.charAt(pos) == testString.charAt(pos2)) {
numChar += 1;
}
}
if (numChar == 1) {
uniqueChar += 1;
uniqueString = uniqueString + " " + testString.charAt(pos)
}
numChar = 0;
}
return uniqueChar;
}
var testString = prompt("Give me a string of characters to check", "");
var lookFor = "startvalue";
while (lookFor.length > 1) {
if (lookFor != "startvalue")
alert("Please select only one character");
lookFor = prompt(testString + "\n\nWhat should character should I look for?", "");
}
document.write("I found " + countChar(testString, lookFor) + " of the<b> " + lookFor + "</B> character");
document.write("<br><br>I counted the following " + findNumberOfUniqueChar(testString) + " unique character(s):");
document.write("<br>" + uniqueString)
</script>
Here is the simplest function to do that
function remove(text)
{
var unique= "";
for(var i = 0; i < text.length; i++)
{
if(unique.indexOf(text.charAt(i)) < 0)
{
unique += text.charAt(i);
}
}
return unique;
}
The one line solution will be to use Set. const chars = [...new Set(s.split(''))];
If you want to return values in an array, you can use this function below.
const getUniqueChar = (str) => Array.from(str)
.filter((item, index, arr) => arr.slice(index + 1).indexOf(item) === -1);
console.log(getUniqueChar("aaabbbccc"));
Alternatively, you can use the Set constructor.
const getUniqueChar = (str) => new Set(str);
console.log(getUniqueChar("aaabbbccc"));
Here is the simplest function to do that pt. 2
const showUniqChars = (text) => {
let uniqChars = "";
for (const char of text) {
if (!uniqChars.includes(char))
uniqChars += char;
}
return uniqChars;
};
const countUnique = (s1, s2) => new Set(s1 + s2).size
a shorter way based on #le_m answer
let unique=myArray.filter((item,index,array)=>array.indexOf(item)===index)

Categories