Zliczanie wystąpień każdego znaku w napisie

0

Witam,
Trafiłem na zadanie, które nie mam pojęcia jakbym mógł poprawnie rozwiązać w JavaScript. Mianowicie mam napisać funkcję, która przyjmuje jakiś napis, a następnie zlicza wystąpienia każdej literki w tym napisie i wypisuje wynik. Problem tkwi w tym, że nie mogę posługiwać się pętlami, ale mogę używać funkcji typu forEach, map, filter, reduce,
Z tego co poczytałem o tych funkcjach i ogólnie o napisach kombinowałem coś z "string.split":

function zadanie1(napis){
	console.log(napis.split( "a" ).length-1);
}

Tylko, że nie mam pomysłu jak to dobrze zmodyfikować bez używania pętli, aby mi dla każdej literki wypisało ile razy występuje, coś kombinowałem z funkcją forEach, ale słabo idzie.

1
var text = 'test string';
var map = {};

text.split('').forEach(function(ch) {
    if(!map.hasOwnProperty(ch)) {
        map[ch] = 0;
    }

    map[ch]++;
});

console.log(map);
0

@jackweb:
Dzięki za pomoc, ale nie wiem czy do końca to rozumiem.
Z tego co czytałem to funkcja "map" na podstawie jednej tablicy generuje drugą.
Dlaczego w linii::

text.split('').forEach(function(ch)

występuje: split('') - dlaczego w nawiasie są ''
a druga sprawa to o co chodzi z użyciem: function(ch) - dlaczego akurat tu w nawiasie jest ch?
i dlaczgo na początku jest:

var map = {}

rozumiem, że tworzymy sobie pusty obiekt o nazwie map tak?

1

map to nazwa zmiennej, może powinienem ją nazwać dict (od słownik) albo jakoś inaczej...

Ogólnie idea jest taka, że split('') tworzy ze stringa tablicę, w której każdy znak jest osobnym elementem. For each przechodzi przez całą tablicę, tak, że ch jest aktualnym znakiem (character). Następnie sprawdzamy, czy taki znak już występuje w słowniku (zmienna map). Jeżeli nie, ustawiamy występowanie na 0. map[ch]++ oznacza, że literka wystąpiła kolejny raz.

1

Można też np tak:

	function count(txt){
		return txt.split('').filter(function(sign){return sign === 'a'}).length;
	};

albo

	function countRegex(txt){
		return txt.match(/a/g).length;
	};
1

Ok, źle spojrzałem. Zasugerowałem się tym 'a' w kodzie. W takim razie to co podał @jackweb albo np.

	function countAll(txt){
		var txtArr = txt.split('');
	
		function countSign(item){
			return txtArr.filter(function(sign){return sign === item}).length;
		};
	
		return Array.from(new Set(txt))
			.map(function(item){
				return {
					name: item, 
					value: countSign(item)
				};
			});
	};
0

@OverMorda: @jackweb
Rzucicie okiem czy dobrze to przekształciłem na taki kod jaki bym chciał:
HTML:

<!doctype html>
<html lang="pl">
   <head>
	 <script type="text/javascript" src="1.js"></script>
   </head>
   <body>
		<script type="text/javascript">
			var napis = "Hello World!";
			zadanie1(napis);
		</script>
   </body>
</html>

JS:

var dict = {};
function zadanie1(napis){
	var tab = napis.split('');
	tab.forEach(pom_f)
	console.log(dict);
}
function pom_f(ch){
	if(!dict.hasOwnProperty(ch)) {
		dict[ch] = 0;
	}
	dict[ch]++;
}

Jedyne co mi nie pasuje to ta zmienna dict poza funkcjami, jakby globalna, czy tak jest OK? Niby działa

2
function zadanie1(napis){
	var dict = {};
	
	function pom_f(ch){
		if(!dict.hasOwnProperty(ch)) {
			dict[ch] = 0;
		}
		dict[ch]++;
	}
	
    napis.split('').forEach(pom_f)
    console.log(dict);
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1