Related
An isogram is a word that has no repeating letters, consecutive or non-consecutive. Implement a function that determines whether a string that contains only letters is an isogram. Assume the empty string is an isogram. Ignore letter case.
function isIsogram(str){
let NewStr = str.toLowerCase();
for ( let i = 0; i < NewStr.length; i++){
for ( let j = i + 1; j < NewStr.length; j++) {
if ( NewStr[i] === NewStr[j]) {
return false }
else {
return true}
}
}
}
This code will return true as soon as it finds two letters that are not equal:
if ( NewStr[i] === NewStr[j]) {
return false }
else {
return true}
What you should do is return false only if the condition passes. If not continue the loop, and return true at the end:
function isIsogram(str) {
let NewStr = str.toLowerCase();
for (let i = 0; i < NewStr.length; i++) {
for (let j = i + 1; j < NewStr.length; j++) {
if (NewStr[i] === NewStr[j]) {
return false
}
}
}
return true;
}
console.log(isIsogram('cdba')); // true
console.log(isIsogram('aa')); // false
console.log(isIsogram('efgaba')); // false
You can also do the same check using a Set. If the number of letters in the Set is equal to the number of letters in the original string, all characters are unique.
function isIsogram(str) {
return new Set(str.toLowerCase()).size === str.length;
}
console.log(isIsogram('cdba')); // true
console.log(isIsogram('aa')); // false
console.log(isIsogram('efgaba')); // false
look what did your code do:
if ( NewStr[i] === NewStr[j]) {
return false }
else {
return true}}
When the condition is true, return false, otherwise return true.
It means that function will be finished at the first time whether NewStr[0] === NewStr[0] is true or not
What you can do:
Store a seen letter. If you have seen a letter before return false.
Use an object for for storing a seel letter, because if unseen, the property returns false
Use only a single loop.
Conclusion:
function isIso(string) {
var seen = {},
i;
string = string.toLowerCase();
for (i = 0; i < string.length; i++) {
if (seen[string[i]]) return false;
seen[string[i]] = true;
}
return true;
}
console.log(isIso('')); // true
console.log(isIso('abc')); // true
console.log(isIso('abbc')); // false
console.log(isIso('abca')); // false
Modern javascript code is simple as
function isIsogram(str){
return str.length === new Set(str.toLowerCase().split('')).size;
}
console.log(isIsogram('abcd'))
console.log(isIsogram('abcb'))
function isIsogram(str){
for(let i=0; i<str.length; i++){
if(str[i] === str[i+1]){
return false
}
}
return true
}
I hope everyone is having a good day.
This is my first ever post on Stackoverflow!
I have just completed the javascript course on codeacademy and have read a couple of books on it too. Now I am on codewars. I would classify myself as a beginner in Javascript.
I find myslef a little stuck on a challenge, please can someone shed some light on what I may be doing wrong? Many thanks in advance!
Here is the instructions:
Check to see if a string has the same amount of 'x's and 'o's. The method must return a boolean and be case insensitive. The string can contains any char.
And here is my code:
function XO(str) {
var x = [];
var o = [];
for (var i = 0; i <= str.length; i++) {
if (str(i).toLowerCase === "x") {
x.push(i);
} else if (str(i).toLowerCase === "o") {
o.push(i);
}
if (x.length === o.length) {
return true;
} else {
return false;
}
}
}
i corrected mistakes and use code comment to explain
function XO(str) {
var x = [];
var o = [];
for (var i = 0; i < str.length; i++) { // i must be lower than length
// str[i] or str.charAt(i), not str(i)
if (str[i].toLowerCase() === 'x') { // toLowerCase is function, it must be called with toLowerCase()
x.push(str[i]); // should push character
} else if (str[i].toLowerCase() === 'o') {
o.push(str[i]);
}
}
// return statement must be located at the end
if (x.length == o.length) {
return true;
} else {
return false;
}
}
console.log(XO('xo'));
console.log(XO('xxo'));
console.log(XO('xoX'));
console.log(XO('xoOX'));
function XO(str) {
var x = 0, // numbers are better
o = 0;
for (var i = 0; i < str.length; i++) { // changed from '<=' to '<'
if (str[i].toLowerCase() === "x") {
x++;
} else if (str[i].toLowerCase() === "o") {
o++;
}
}
return x === o;
}
str.match(/x/g).length==str.match(/o/g).length
function checkIfOequalsX(str){
return str.match(/x/g).length==str.match(/o/g).length
}
console.log(checkIfOequalsX('xxooxo'));
console.log(checkIfOequalsX('xxooxoo'));
you can do it with
str.match(/x/g).length==str.match(/o/g).length
The third if else will never be executed because for a string there will be always a value.
If you want to return the count then the check of length should be performed after the for loop.
var xCount = 0; var oCount = 0;
for (var i = 0; i < str.length; i++) {
if (str[i].toLowerCase() === "x") {
xCount++;
} else if (str[i].toLowerCase() === "o") {
oCount++;
}
}
return xCount === oCount;
About another solutions containing the check based on str.match method, the complexity of using that piece of code is twice compared to above because the str.match loop is performed twice to match both the strings.
function XO(str) {
let strn = str.toLowerCase();
let countX = [];
let countO = [];
for(let i=0; i<strn.length; i++) {
if(strn[i] == 'x') {
countX.push(strn[i])
} else if(strn[i] == 'o') {
countO.push(strn[i])
}
}
if(countX.length == countO.length){
return true
} else if(countX.length !== countO.length) {
return false
}
}
You can use the Regex for finding those characters:
function XO(str) {
return str.match(/o/ig).length === str.match(/x/ig).length;
}
function XO(str) {
let letraO = 0
let letraX = 0
const myArray = str.toLowerCase();
for (i=0; i<myArray.length; i++){
myArray[i] === 'o'? letraO++ : letraX ++
}
return letraO===letraX? true : false
}
function XO(str) {
// make the string lowercase because we are case insensitive
str = str.toLowerCase();
// put the string into an array
var arrayOfCharacters = str.split("");
//count the x's
var countX = arrayOfCharacters.reduce( function( n, val ) {
return n + (val === 'x');
}, 0);
// count the o's
var countO = arrayOfCharacters.reduce( function( n, val ) {
return n + (val === 'o');
}, 0);
// do these numbers match? if so return true and if not return false
if ( countX == countO ) {
return true;
} else {
return false;
}
}
I was wondering if there is a way to check for repeated characters in a string without using double loop. Can this be done with recursion?
An example of the code using double loop (return true or false based on if there are repeated characters in a string):
var charRepeats = function(str) {
for(var i = 0; i <= str.length; i++) {
for(var j = i+1; j <= str.length; j++) {
if(str[j] == str[i]) {
return false;
}
}
}
return true;
}
Many thanks in advance!
This will do:
function hasRepeats (str) {
return /(.).*\1/.test(str);
}
(A recursive solution can be found at the end of this answer)
You could simply use the builtin javascript Array functions some MDN some reference
var text = "test".split("");
text.some(function(v,i,a){
return a.lastIndexOf(v)!=i;
});
callback parameters:
v ... current value of the iteration
i ... current index of the iteration
a ... array being iterated
.split("") create an array from a string
.some(function(v,i,a){ ... }) goes through an array until the function returns true, and ends than right away. (it doesn't loop through the whole array, which is good for performance)
Details to the some function here in the documentation
Here some tests, with several different strings:
var texts = ["test", "rest", "why", "puss"];
for(var idx in texts){
var text = texts[idx].split("");
document.write(text + " -> " + text.some(function(v,i,a){return a.lastIndexOf(v)!=i;}) +"<br/>");
}
//tested on win7 in chrome 46+
If you will want recursion.
Update for recursion:
//recursive function
function checkString(text,index){
if((text.length - index)==0 ){ //stop condition
return false;
}else{
return checkString(text,index + 1)
|| text.substr(0, index).indexOf(text[index])!=-1;
}
}
// example Data to test
var texts = ["test", "rest", "why", "puss"];
for(var idx in texts){
var txt = texts[idx];
document.write( txt + " ->" + checkString(txt,0) + "<br/>");
}
//tested on win7 in chrome 46+
you can use .indexOf() and .lastIndexOf() to determine if an index is repeated. Meaning, if the first occurrence of the character is also the last occurrence, then you know it doesn't repeat. If not true, then it does repeat.
var example = 'hello';
var charRepeats = function(str) {
for (var i=0; i<str.length; i++) {
if ( str.indexOf(str[i]) !== str.lastIndexOf(str[i]) ) {
return false; // repeats
}
}
return true;
}
console.log( charRepeats(example) ); // 'false', because when it hits 'l', the indexOf and lastIndexOf are not the same.
function chkRepeat(word) {
var wordLower = word.toLowerCase();
var wordSet = new Set(wordLower);
var lenWord = wordLower.length;
var lenWordSet =wordSet.size;
if (lenWord === lenWordSet) {
return "false"
} else {
return'true'
}
}
Using regex to solve=>
function isIsogram(str){
return !/(\w).*\1/i.test(str);
}
console.log(isIsogram("isogram"), true );
console.log(isIsogram("aba"), false, "same chars may not be adjacent" );
console.log(isIsogram("moOse"), false, "same chars may not be same case" );
console.log(isIsogram("isIsogram"), false );
console.log(isIsogram(""), true, "an empty string is a valid isogram" );
The algorithm presented has a complexity of (1 + n - (1)) + (1 + n - (2)) + (1 + n - (3)) + ... + (1 + n - (n-1)) = (n-1)*(1 + n) - (n)(n-1)/2 = (n^2 + n - 2)/2 which is O(n2).
So it would be better to use an object to map and remember the characters to check for uniqueness or duplicates. Assuming a maximum data size for each character, this process will be an O(n) algorithm.
function charUnique(s) {
var r = {}, i, x;
for (i=0; i<s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
On a tiny test case, the function indeed runs a few times faster.
Note that JavaScript strings are defined as sequences of 16-bit unsigned integer values. http://bclary.com/2004/11/07/#a-4.3.16
Hence, we can still implement the same basic algorithm but using a much quicker array lookup rather than an object lookup. The result is approximately 100 times faster now.
var charRepeats = function(str) {
for (var i = 0; i <= str.length; i++) {
for (var j = i + 1; j <= str.length; j++) {
if (str[j] == str[i]) {
return false;
}
}
}
return true;
}
function charUnique(s) {
var r = {},
i, x;
for (i = 0; i < s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charUnique2(s) {
var r = {},
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charCodeUnique(s) {
var r = [],
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s.charCodeAt(i);
if (r[x])
return false;
r[x] = true;
}
return true;
}
function regExpWay(s) {
return /(.).*\1/.test(s);
}
function timer(f) {
var i;
var t0;
var string = [];
for (i = 32; i < 127; i++)
string[string.length] = String.fromCharCode(i);
string = string.join('');
t0 = new Date();
for (i = 0; i < 10000; i++)
f(string);
return (new Date()) - t0;
}
document.write('O(n^2) = ',
timer(charRepeats), ';<br>O(n) = ',
timer(charUnique), ';<br>optimized O(n) = ',
timer(charUnique2), ';<br>more optimized O(n) = ',
timer(charCodeUnique), ';<br>regular expression way = ',
timer(regExpWay));
let myString = "Haammmzzzaaa";
myString = myString
.split("")
.filter((item, index, array) => array.indexOf(item) === index)
.join("");
console.log(myString); // "Hamza"
Another way of doing it using lodash
var _ = require("lodash");
var inputString = "HelLoo world!"
var checkRepeatition = function(inputString) {
let unique = _.uniq(inputString).join('');
if(inputString.length !== unique.length) {
return true; //duplicate characters present!
}
return false;
};
console.log(checkRepeatition(inputString.toLowerCase()));
const str = "afewreociwddwjej";
const repeatedChar=(str)=>{
const result = [];
const strArr = str.toLowerCase().split("").sort().join("").match(/(.)\1+/g);
if (strArr != null) {
strArr.forEach((elem) => {
result.push(elem[0]);
});
}
return result;
}
console.log(...repeatedChar(str));
You can also use the following code to find the repeated character in a string
//Finds character which are repeating in a string
var sample = "success";
function repeatFinder(str) {
let repeat="";
for (let i = 0; i < str.length; i++) {
for (let j = i + 1; j < str.length; j++) {
if (str.charAt(i) == str.charAt(j) && repeat.indexOf(str.charAt(j)) == -1) {
repeat += str.charAt(i);
}
}
}
return repeat;
}
console.log(repeatFinder(sample)); //output: sc
const checkRepeats = (str: string) => {
const arr = str.split('')
const obj: any = {}
for (let i = 0; i < arr.length; i++) {
if (obj[arr[i]]) {
return true
}
obj[arr[i]] = true
}
return false
}
console.log(checkRepeats('abcdea'))
function repeat(str){
let h =new Set()
for(let i=0;i<str.length-1;i++){
let a=str[i]
if(h.has(a)){
console.log(a)
}else{
h.add(a)
}
}
return 0
}
let str = '
function repeat(str){
let h =new Set()
for(let i=0;i<str.length-1;i++){
let a=str[i]
if(h.has(a)){
console.log(a)
}else{
h.add(a)
}
}
return 0
}
let str = 'haiiiiiiiiii'
console.log(repeat(str))
'
console.log(repeat(str))
Cleanest way for me:
Convert the string to an array
Make a set from the array
Compare the length of the set and the array
Example function:
function checkDuplicates(str) {
const strArray = str.split('');
if (strArray.length !== new Set(strArray).size) {
return true;
}
return false;
}
You can use "Set object"!
The Set object lets you store unique values of any type, whether
primitive values or object references. It has some methods to add or to check if a property exist in the object.
Read more about Sets at MDN
Here how i use it:
function isIsogram(str){
let obj = new Set();
for(let i = 0; i < str.length; i++){
if(obj.has(str[i])){
return false
}else{
obj.add(str[i])
}
}
return true
}
isIsogram("Dermatoglyphics") // true
isIsogram("aba")// false
So I tried looking for this in the search but the closest I could come is a similar answer in several different languages, I would like to use Javascript to do it.
The problem is I have an arbitrary string that I would like to return the first non repeating character. EX: 'aba' -> would return b
'aabcbd' -> would return c.
This is what I have so far, just a simple for loop to start.
var someString = 'aabcbd';
var firstNonRepeatedCharacter = function(string) {
for(var i = 0; i < someString.length; i++){
}
};
http://jsfiddle.net/w7F87/
Not sure where to go from here
You can use the indexOf method to find the non repeating character. If you look for the character in the string, it will be the first one found, and you won't find another after it:
function firstNonRepeatedCharacter(string) {
for (var i = 0; i < string.length; i++) {
var c = string.charAt(i);
if (string.indexOf(c) == i && string.indexOf(c, i + 1) == -1) {
return c;
}
}
return null;
}
Demo: http://jsfiddle.net/Guffa/Se4dD/
If you're looking for the first occurrence of a letter that only occurs once, I would use another data structure to keep track of how many times each letter has been seen. This would let you do it with an O(n) rather than an O(n2) solution, except that n in this case is the larger of the difference between the smallest and largest character code or the length of the string and so not directly comparable.
Note: an earlier version of this used for-in - which in practice turns out to be incredibly slow. I've updated it to use the character codes as indexes to keep the look up as fast as possible. What we really need is a hash table but given the small values of N and the small, relative speed up, it's probably not worth it for this problem. In fact, you should prefer #Guffa's solution. I'm including mine only because I ended up learning a lot from it.
function firstNonRepeatedCharacter(string) {
var counts = {};
var i, minCode = 999999, maxCode = -1;
for (i = 0; i < string.length; ++i) {
var letter = string.charAt(i);
var letterCode = string.charCodeAt(i);
if (letterCode < minCode) {
minCode = letterCode;
}
if (letterCode > maxCode) {
maxCode = letterCode;
}
var count = counts[letterCode];
if (count) {
count.count = count.count + 1;
}
else {
counts[letterCode] = { letter: letter, count: 1, index: i };
}
}
var smallestIndex = string.length;
for (i = minCode; i <= maxCode; ++i) {
var count = counts[i];
if (count && count.count === 1 && count.index < smallestIndex) {
smallestIndex = count.index;
}
}
return smallestIndex < string.length ? string.charAt(smallestIndex) : '';
}
See fiddle at http://jsfiddle.net/b2dE4/
Also a (slightly different than the comments) performance test at http://jsperf.com/24793051/2
var firstNonRepeatedCharacter = function(string) {
var chars = string.split('');
for (var i = 0; i < string.length; i++) {
if (chars.filter(function(j) {
return j == string.charAt(i);
}).length == 1) return string.charAt(i);
}
};
So we create an array of all the characters, by splitting on anything.
Then, we loop through each character, and we filter the array we created, so we'll get an array of only those characters. If the length is ever 1, we know we have a non-repeated character.
Fiddle: http://jsfiddle.net/2FpZF/
Two further possibilities, using ECMA5 array methods. Will return undefined if none exist.
Javascript
function firstNonRepeatedCharacter(string) {
return string.split('').filter(function (character, index, obj) {
return obj.indexOf(character) === obj.lastIndexOf(character);
}).shift();
}
console.log(firstNonRepeatedCharacter('aabcbd'));
On jsFiddle
Or if you want a bit better performance, especially on longer strings.
Javascript
function firstNonRepeatedCharacter(string) {
var first;
string.split('').some(function (character, index, obj) {
if(obj.indexOf(character) === obj.lastIndexOf(character)) {
first = character;
return true;
}
return false;
});
return first;
}
console.log(firstNonRepeatedCharacter('aabcbd'));
On jsFiddle
I came accross this while facing similar problem. Let me add my 2 lines.
What I did is a similar to the Guffa's answer. But using both indexOf method and lastIndexOf.
My mehod:
function nonRepeated(str) {
for(let i = 0; i < str.length; i++) {
let j = str.charAt(i)
if (str.indexOf(j) == str.lastIndexOf(j)) {
return j;
}
}
return null;
}
nonRepeated("aabcbd"); //c
Simply, indexOf() gets first occurrence of a character & lastIndexOf() gets the last occurrence. So when the first occurrence is also == the last occurence, it means there's just one the character.
Here's a Solution using Regex to replace all repeating characters and then returning the first character.
function firstNonRepeat(str) {
// Sorting str so that all repeating characters will come together & replacing it with empty string and taking first character using substr.
var rsl = str.split('').sort().join('').replace(/(\w)\1+/g,'').substr(0,1);
if(rsl) return rsl;
else return 'All characters are repeated in ' + str;
}
console.log(firstNonRepeat('aaabcccdeeef'));
console.log(firstNonRepeat('aaacbdcee'));
console.log(firstNonRepeat('aabcbd'));
First of all, start your loop at 1, not 0. There is no point in checking the first character to see if its repeating, obviously it can't be.
Now, within your loop, you have someString[i] and someString[i - 1]. They are the current and previous characters.
if someString[i] === someString[i - 1] then the characters are repeating, if someString[i] !== someString[i - 1] then they are not repeating, so you return someString[i]
I won't write the whole thing out for you, but hopefully the thought process behind this will help
function FirstNotRepeatedChar(str) {
var arr = str.split('');
var result = '';
var ctr = 0;
for (var x = 0; x < arr.length; x++) {
ctr = 0;
for (var y = 0; y < arr.length; y++) {
if (arr[x] === arr[y]) {
ctr+= 1;
}
}
if (ctr < 2) {
result = arr[x];
break;
}
}
return result;
}
console.log(FirstNotRepeatedChar('asif shaik'));
Here's an O(n) solution with 2 ES6 Sets, one tracking all characters that have appeared and one tracking only chars that have appeared once. This solution takes advantage of the insertion order preserved by Set.
const firstNonRepeating = str => {
const set = new Set();
const finalSet = new Set();
str.split('').forEach(char => {
if (set.has(char)) finalSet.delete(char);
else {
set.add(char);
finalSet.add(char);
}
})
const iter = finalSet.values();
return iter.next().value;
}
let arr = [10, 5, 3, 4, 3, 5, 6];
outer:for(let i=0;i<arr.length;i++){
for(let j=0;j<arr.length;j++){
if(arr[i]===arr[j+1]){
console.log(arr[i]);
break outer;
}
}
}
//or else you may try this way...
function firstDuplicate(arr) {
let findFirst = new Set()
for (element of arr)
if (findFirst.has(element ))
return element
else
findFirst.add(element )
}
function firstUniqChar(str) {
let myMap = new Map();
for(let i = 0; i < str.length; i++) {
let char = str.charAt(i);
if(!myMap.has(char)) {
myMap.set(char, 0);
}
myMap.set(char, myMap.get(char) + 1 );
}
for(let [key, value] of myMap) {
if(value === 1) {
return key;
}
}
return null;
}
let result = firstUniqChar("caabbdccee");
console.log(result);
You can use Map Object and set key and value, where in value you store the count for that particular character, After that you can iterate over map and check where is value 1 and return that key.
Map Object remembers the original insertion order of the keys.
This solution should works with array with integers and string.
function firstNoneRepeating(list, map = new Map()) {
for (let item of list) {
if (map.has(item)) {
map.set(item, map.get(item) + 1);
} else {
map.set(item, 1);
}
}
for (let [key, value] of map.entries()) {
if (value === 1) {
return key;
}
}
}
console.log(firstNoneRepeating("aabcbd"));
console.log(firstNoneRepeating([5, 2, 3, 4, 2, 6, 7, 1, 2, 3]));
let str='aabcbd'
let ans=''
for (let i=0;i<str.length;i++){
if(str.indexOf(str.charAt(i))===str.lastIndexOf(str.charAt(i))){
ans+=str.charAt(i)
break
}
}
console.log(ans)
Fill an empty array with zeros, with same length as the string array, and tally up how many times they appear through the loop. Grab the first one in the tallied array with a value of 1.
function firstNotRepeatingCharacter(s) {
const array = s.split("");
let scores = new Array(array.length).fill(0);
for (let char of array) {
scores[array.indexOf(char)]++;
}
const singleChar = array[scores.indexOf(1)];
return singleChar ? singleChar : "_"
}
You can iterate through each character to find() the first letter that returns a single match(). This will result in the first non-repeated character in the given string:
const first_nonrepeated_character = string => [...string].find(e => string.match(new RegExp(e, 'g')).length === 1);
const string = 'aabcbd';
console.log(first_nonrepeated_character(string)); // c
Here is my solution which have time complexity of o(n)
function getfirstNonRepeatingCharacterInAString(params) {
let count = {};
for (let i = 0; i < params.length; i++) {
let count1 = 0;
if (!count[params.charAt(i)]) {
count[params.charAt(i)] = count1 + 1;
}
else {
count[params.charAt(i)] = count[params.charAt(i)] + 1;
}
}
for (let key in count) {
if (count[key] === 1) {
return key;
}
}
return null;
}
console.log(getfirstNonRepeatingCharacterInAString("GeeksfoGeeks"));
Here is my solution using forEach and convert the string into an array
function firstNotRepeatingCharacter(s) {
var strArr = s.split("");
var found = "_";
strArr.forEach(function(item, index) {
if (strArr.indexOf(item) == index && strArr.indexOf(item, index + 1) == -1) {
if (found === "_") {
found = item;
}
}
})
return found;
}
firstNotRepeatingCharacter("abacabad")
Here is another approach:
Everytime you find equal chars store it in an array and break out of the loop. If the char is not found in the array then you have your first nonRepeating char
function nonRepeatingChars(value) {
const memory = []
for (let i = 0; i < value.length; i++) {
for (let j = i + 1; j < value.length; j++) {
if (value[i] === value[j]) {
memory.push(value[j])
break;
}
}
if (!memory.some(x => x === value[i])) {
return value[i];
}
}
return "all chars have duplicates";
}
console.log('First non repeating char is:',nonRepeatingChars("esen"))
console.log('First non repeating char is:',nonRepeatingChars("esesn"))
console.log('First non repeating char is:',nonRepeatingChars("eseulsn"))
console.log('First non repeating char is:',nonRepeatingChars("esesnn"))
> var firstNonRepeatedCharacter = function (str){
> for(i=0;i<str.length;i++){
> if(str.indexOf(str.charAt(i)) === str.lastIndexOf(str.charAt(i))){
> console.log(str.charAt(i));
> break;
> } } }
>
> firstNonRepeatedCharacter ("areerak");
you can check below link
https://codepen.io/t3veni/pen/wvvxJzm
Easy way to solve this algorithm, very straight forward.
function firstNonRepeatChar(str){
let map = {};
for(let i=0; i<str.length; i++){
if(Object.keys(map).includes(str[i])){
map[str[i]]++
}
else{
map[str[i]] = 1;
}
}
for(let j=0; j< Object.values(map).length; j++){
if(Object.values(map)[j] == 1){
console.log(Object.keys(map)[j]);
return
}
if (j == Object.values(map).length-1 && Object.values(map)[j] != 1){
console.log('_');
return;
}
else{
continue;
}
}
}
nonRepeat("aaabbcccdeeef");
Here is one other solution just using array, using 26 unique character as length of array:
var firstUniqChar = (function(s) {
var arr = [];
var str = s.toLowerCase();
for(let c of str){
let index = c.charCodeAt(0) - "a".charCodeAt(0);
arr[index]? ++arr[index]: arr[index]=1;
}
for(let c of str){
let index = c.charCodeAt(0) - 97;
if(arr[index] == 1){
return c;
};
}
return -1;
}("aabcbd"));
console.log(firstUniqChar);
We can keep track of frequency of each character of the string in an object.
For example : for "aabcbd" we can store the frequency as
{ "a":2, "b":2, "c":1, "d":1 }
This will take O(n) time.
Then we can traverse over this object and find the first character with frequency 1, which will also take O(n) time. So, the time complexity for this approach will be O(n).
const firstNonRepeating=(str)=>{
const obj={};
str.split("").forEach(item=>{
obj[item]
? obj[item]++
: obj[item]=1;
});
const item = Object.keys(obj).find(key=> obj[key] === 1);
return item;
}
Note: I use ES6 Object.keys method which may not work in older
browsers.
//To find first non repeating letter
//It will check for both upper and lower case
//only use one String.indexOf()
var mystr="ohvhvtccggt";
var checkFirstNonRepeating=function(){
var ele=[];
for(var i=0;i<mystr.length;i++) {
var key=mystr.charAt(i);
if(!ele[key])
ele[key]=0;
ele[key]++;
//Just check for second occurance of character
//no need to use indexOf twice
if(mystr.indexOf(key,i+1)==-1 && ele[key]<2)
return mystr[i];
}
return "All repeating letters";
}
console.log(checkFirstNonRepeating());
/*
Input : "ohvhvtoccggt"
Output : All repeating letters
Input :"oohjtht"
Output :j
*/
I used object to keep track of characters count in a string then return the char that has the fa value of 1. Here is a demo:
function firstNotRepeatingCharacter(s) {
// initialize an empty object to store chars
let seen = {};
let letter = '';
// iterate over each char in a string
// if it is already there increase value by one
// else set the value to 1
for(let char of s){
if (seen[char]){
seen[char] +=1;
} else {
seen[char] = 1;
}
}
// iterate over the new constructed object
// if the value is 1 and the output variable is empty
// return the associated key to the value 1
// else return '_'
for(let v in seen){
while(seen[v] == 1 && letter === ''){
letter += v;
return letter;
}
}
return('_');
}
console.log(firstNotRepeatingCharacter("abacabad"));
console.log(firstNotRepeatingCharacter("cbc"));
console.log(firstNotRepeatingCharacter("bcccccccccccccyb"));
console.log(firstNotRepeatingCharacter("aaa"));
The most satisfactory and easy to understand answer is the following.
function firstNotRepeatingCharacter(s) {
const arr = s.split("");
for(let i = 0; i < arr.length; i++){
let chr = arr[i];
if( arr.indexOf(arr[i]) == arr.lastIndexOf(arr[i])){
return arr[i]
}
}
return "_"
}
Explanation: It loops through all the characters of a string from forward and backward and then compares the values. If the index of both forward and backward search is true then it returns that character.
let str = 'aabbcdd';
let val = str.split('').reduce((a, e)=>{ if(str.indexOf(e) == str.lastIndexOf(e)) {a = e }; return a})
console.log(val); // c
the implementation below has a good time complexity and it accounts for letters with different cases:
steps
must touch every character in the string to know if it's repeated or not
function firstNonRepeatingLetter(wordd) {
const chars = {}
let word = wordd.toLowerCase()
// go through chars
// store chars in hash with values of array storing index of char and true if only 1 encountered so far
for (let i = 0; i < word.length; i += 1) {
let char = word[i]
if (chars[char]) {
chars[char][0] = false
} else {
chars[char] = [true, i]
}
}
let output = ''
let index;
for (let key in chars) {
// return char with true and lowest index
if (chars[key][0]) {
index = index === undefined ? chars[key][1] : index
if (index >= chars[key][1]) {
output = key
}
}
}
return index === undefined ? '' : wordd[index]
}
console.log(firstNonRepeatingLetter('sTreSS')) //T```
The bellow solution is a kind of frequency counter pattern and it will run only one loop, so O(n) will be the time complexity.
function firstNotRepeatingCharacter(str) {
const obj = {};
for (let i = 0, L = str.length; i < L; i++) {
const char = str[i];
obj[char] = obj[char] ? obj[char] + 1 : 1;
}
for (let key of Object.keys(obj)) {
if (obj[key] == 1) {
return key;
}
}
return -1;
}
Here is another solution
function firstNotRepeatingCharacter(s) {
const obj = {};
for (let i of s) {
if(!obj[i]) {
obj[i] = 1;
} else if (obj[i]) {
obj[i] = +obj[i] + 1;
}
}
for (let [key, value] of Object.entries(obj)) {
if(value == 1) return key;
}
return "_"
}
Using below method can achieve first non repeated character
function main(str) {
str = String(str).toLowerCase();
let non_repeated_char = 'N/A';
for (let i = 0; i < str.length; i++) {
let currentChar = str[i];
let repeated_times = String(str).split('').filter(e => e == currentChar).length;
if (repeated_times === 1) {
non_repeated_char = currentChar;
break;
}
}
return non_repeated_char;
};
let Result = main("basketball");
console.log("The Non Repeated char is-->", Result);
Have an array set up with a[letter][occurences], but struggling with looping through this array, to check for occurences > 1 and removing the ones that are.
function charFreq(s) {
var i, j;
var a = new Array();
for (j = 0; j < s.length; j++) {
for (i = 0; i < a.length; i++) {
if (a[i][0] == s[j]) {
a[i][1]++;
break;
}
}
if (i == a.length) {
a[i] = [s[j], 1];
}
}
return a[i][0];
}
document.write(charFreq("insert string here"));
This is the mess I've come up with so far:
function check(str) {
var c;
for (c=0; c < a.length; c++) {
if(a[c][1] == 1) {
return true;
break;
} else {
return false;
}
}
}
Using ES6 Set:
// :: unique = Array<any>|string => Array<any>
const unique = xs => [...new Set(xs)]
const dedupe = str => unique(str).join('')
console.log(
unique('foo'), // => ['f', 'o']
dedupe('foo'), // => 'fo'
)
Don't do it that way.
function noDups( s ) {
var chars = {}, rv = '';
for (var i = 0; i < s.length; ++i) {
if (!(s[i] in chars)) {
chars[s[i]] = 1;
rv += s[i];
}
}
return rv;
}
alert(noDups("Shoe fly pie, and apple pan dowdy")); // Shoe flypi,andw
As the length of your string gets longer, your code gets slower by a factor roughly equal to the square of the length of the string.
To delete duplicate characters from an string, you can use the next function that made the user #Cerbrus
function find_unique_characters( string ){
var unique='';
for(var i=0; i<string.length; i++){
if(string.lastIndexOf(string[i]) == string.indexOf(string[i])){
unique += string[i];
}
}
return unique;
}
console.log(find_unique_characters('baraban'));
If you only want to return characters that appear occur once in a
string, check if their last occurrence is at the same position as
their first occurrence.
Your code was returning all characters in the string at least once,
instead of only returning characters that occur no more than once
Link to the thread of stackoverflow Remove duplicate characters from string
Here's a quick way:
str = str.split('').filter(function(v,i,self){
return self.indexOf(v) == i;
}).join('');
function RemoveDuplicateLetters(input) {
var result = '', i = 0, char = '';
while (i < input.length) {
char = input.substring(i, i+1);
result += char;
input = input.replace(char,'');
}
return result;
}
I can't see a splice version, so here's one:
function uniqueChars(s) {
var s = s.split('');
var c, chars = {}, i = 0;
while ((c = s[i])) {
c in chars? s.splice(i, 1) : chars[c] = ++i;
}
return s.join('');
}
This assumes only alpha characters, and upper case not equal to lower case.
function uniqueChars(string){
var i= 0, L= string.length, ustring= '', next;
while(i<L){
next= string.charAt(i++);
if(ustring.indexOf(next)== -1) ustring+= next;
}
return ustring.replace(/[^a-zA-Z]/g, '');
}
var s1= 'The quick red fox jumps over the lazy brown dog.';
uniqueChars(s1)
/* returned value: (String)
Thequickrdfoxjmpsvtlazybwng
*/
This returns any unique character-
function uniqueArray(array){
return array.filter(function(itm, i, T){
return T.indexOf(itm)== i;
});
}
var s1= 'The quick red fox jumps over the lazy brown dog.';
uniqueArray(s1.split('')).join('');
/* returned value: (String)
The quickrdfoxjmpsvtlazybwng.
*/