Я хочу подсчитать все символы в строке и вернуть ее объекту. Я попытался, но я не смог получить правильный ответ.
Это мой код:
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 }
Очевидно, что это неправильно.
Может ли кто-нибудь помочь мне в этом? Где я ошибаюсь?
Минимальное необходимое изменение состоит в том, что 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
, что falsey, так, то 0
будет использоваться. В следующий раз, когда вы столкнетесь с этой буквой obj[s]
будет 1
, что является правдой.
Я бы использовал операцию уменьшения, например
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)
На самом деле вы можете рассчитывать на лучшую производительность, вы зацикливаете больше, чем вам нужно!
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'));
Проблема здесь в том, что вы назначаете 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;
}
}
Я думаю, вам не нужно использовать forEach
и цикл for
когда вы можете сделать это только для 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'));
Надеюсь, поможет :)
вы должны принести 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
.
Я понимаю, что это не самый красивый, но я надеюсь, что он показывает, как вы можете использовать консоль, чтобы помочь отлаживать циклы.
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'));