2017-06-13 28 views
1

我想计算字符串中的所有字符并将其返回给对象。我已经尝试过,但我无法得到正确的答案。计算字符串中的所有字符

这是我的代码:

function countAllCharacters(str) { 
 
    var a = str.split(""); 
 
    var obj = {}; 
 
    a.forEach(function(s){ 
 
    var count=0; 
 
    for(var j=0;j<a.length;j++){ 
 
     if(s==a[j]){ 
 
     count+=1; 
 
     } 
 
     obj[a[j]]=count; 
 
    } 
 
    }); 
 
    return obj; 
 
} 
 
console.log(countAllCharacters('banana'));

输出:

{ b: 0, a: 3, n: 2 } 

这显然是错误的。

任何人都可以帮助我吗?我哪里出错了?

+2

你为什么使用嵌套循环? – nnnnnn

+0

你能否详细说明并给出正确的代码? –

+2

你真的只需要'obj [s] =(obj [s] || 0)+ 1;'在forEach'回调中。但是,计数字符通常使用'reduce'而不是'forEach'完成。 – Xufox

回答

4

必要的最小变化是obj[a[j]]=count;应该是obj[s]=count;,因为无论j是否引用您当前计算的字母,您都会在内部循环的每次迭代中运行该行。

function countAllCharacters(str) { 
 
    var a = str.split(""); 
 
    var obj = {}; 
 
    a.forEach(function(s){ 
 
    var count=0; 
 
    for(var j=0;j<a.length;j++){ 
 
     if(s==a[j]){ 
 
     count+=1; 
 
     } 
 
     obj[s]=count; 
 
    } 
 
    }); 
 
    return obj; 
 
} 
 
console.log(countAllCharacters('banana'));

但是,你并不需要一个嵌套循环。你的外.forEach()可以更新计数直接在当前信:

function countAllCharacters(str) { 
 
    var a = str.split(""); 
 
    var obj = {}; 
 
    a.forEach(function(s){ 
 
    obj[s] = (obj[s] || 0) + 1; 
 
    }); 
 
    return obj; 
 
} 
 
console.log(countAllCharacters('banana'));

这可以用.reduce()变短:

function countAllCharacters(str) { 
 
    return str.split("").reduce(function(obj, s){ 
 
    obj[s] = (obj[s] || 0) + 1; 
 
    return obj; 
 
    }, {}); 
 
} 
 
console.log(countAllCharacters('banana'));

注意(obj[s] || 0)指 如果是真的,请使用obj[s]的值,否则使用0。所以你第一次遇到一个特定的字母obj[s]将会是undefined,这是错误的,那么0将被使用。下次你遇到那封信obj[s]将是1,这是真的。

1

我认为你需要不使用forEachfor循环在一起的时候,你可以只用foreach做到这一点。这是代码。

function countAllCharacters(str) { 
 
    var a = str.split(""); 
 
    var obj = {}; 
 
    a.forEach(function(s) { 
 
    if (obj[s]) { 
 
     obj[s] = obj[s] + 1; 
 
    } else { 
 
     obj[s] = 1; 
 
    } 
 
    }); 
 
    return obj; 
 
} 
 

 
console.log(countAllCharacters('banana'));

希望它能帮助:)

+0

那真的很有帮助。非常感谢。 –

1

的这里的问题是,你分配obj[a[j]] = count;当计数尚未完成。你应该做的更改function(s)这样:

function(s){ 
    var count=0; 
    for(var j=0;j<a.length;j++){ 
     if(s==a[j]){ 
     count+=1; 
     } 
    } 
    obj[s]=count; 
    } 

另一评论:你的代码是非常低效的,这是O(n^2)。你可以更进一步简化它得到一个O(n)算法是:

function(s){ 
    if (obj[s] == undefined) { 
     obj[s] = 1; 
    } else { 
     obj[s] = obj[s] + 1; 
    } 
    } 
3

其实你可以通过更好的性能算,你环比你更需要!

function countAllCharacters(str) { 
 
    var a = str.split(""); 
 
    var obj = {}; 
 
    for(var j=0;j<a.length;j++){ 
 
    if(typeof obj[a[j]] !== 'undefined'){ 
 
     obj[a[j]]+=1; 
 
    } else { 
 
     obj[a[j]]=1; 
 
    } 
 
    } 
 
    return obj; 
 
} 
 
console.log(countAllCharacters('banana'));

4

我会使用一个减少操作,像这样

const str = "banana" 
 
const charCounts = Array.from(str).reduce((counts, char) => { 
 
    counts[char] = (counts[char] || 0) + 1 
 
    return counts 
 
}, Object.create(null)) 
 

 
console.info(charCounts)

0

我知道这是不是最漂亮的,但我希望它展示了如何使用控制台来帮助调试循环。

function countAllCharacters(str) { 
    var a = str.split(""); 
    var obj = {}; 
    a.forEach(function(s){ 
    console.log(s); 
    var count=0; 
    for(var j in a){ 

     // commas can come in really handy and help avoid huge debug blocks. 
     console.log('_',j,s,a[j]); 

     if(s==a[j]){ 
     console.log('count++'); 
     count++; 
     } 
     obj[s] = count; 
    } 
    }); 
    return obj; 
} 

console.log(countAllCharacters('banana')); 
0

,你必须把你的obj[a[j]]=count声明if里面。

,应返回正确的结果

function countAllCharacters(str) { 
    var a = str.split("") 
    var obj = {} 
    a.forEach(function(s){ 
    var count=0 
    for(var j=0;j<a.length;j++){ 
     if(s===a[j]){ 
     count+=1 
     obj[a[j]]=count 
     } 
    } 
    }) 
    return obj 
} 
console.log(countAllCharacters('banana')) 

obj增量还必须满足if声明。