String split and count the number of occurrences and also - javascript

I have a string
var stringIHave = "Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$";
How to get the count of the number of occurrences of each entry, The occurrence I get, is from a JSON like Java = 8 and etc...

First of all you need to split your srting to array:
var keywordsArr = stringIHave.split( '$$' );
then you need to have an object for example to store counts:
var occur = {};
and then just create simple for loop to count all occurrences:
for( var i = 0; i < keywordsArr.length; i++ ) {
occur[ keywordsArr[ i ] ] = ( occur[ keywordsArr[ i ] ] || 0 ) + 1;
}
now your object occur will have names as keys and count as values.
See jsFiddle demo.
Also as you have at end of your string $$ you maybe will need to remove last item from keywordsArr so just do after split function call:
keywordsArr.pop();
See demo without last element.
So final code will be like:
var stringIHave = "Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$",
keywordsArr = stringIHave.split( '$$' ),
occur = {};
keywordsArr.pop();
for( var i = 0; i < keywordsArr.length; i++ ) {
occur[ keywordsArr[ i ] ] = ( occur[ keywordsArr[ i ] ] || 0 ) + 1;
}
for( var key in occur ) {
document.write( key + ' - ' + occur[key] + '<br/>' );
} ​

I'd suggest the following:
function stringCount(haystack, needle) {
if (!needle || !haystack) {
return false;
}
else {
var words = haystack.split(needle),
count = {};
for (var i = 0, len = words.length; i < len; i++) {
if (count.hasOwnProperty(words[i])) {
count[words[i]] = parseInt(count[words[i]], 10) + 1;
}
else {
count[words[i]] = 1;
}
}
return count;
}
}
console.log(stringCount("Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$", '$$'));
​
JS Fiddle demo.
References:
Object.hasOwnProperty().
parseInt().
String.split().

It's not entirely clear what final objective is. Following creates an object from string that looks like
Object created:
{
"Java": 8,
"jQuery": 4,
"Hibernate": 1,
"Spring": 1,
"Instagram": 1
}
JS:
var str = 'Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$';
var arr = str.split('$$')
var obj = {};
for (i = 0; i < arr.length; i++) {
if (arr[i] != '') {
if (!obj[arr[i]]) {
obj[arr[i]] = 0;
}
obj[arr[i]]++;
}
}
You can loop over the object to get all values or simply look up one value
var jQueryOccurences= obj['jQuery'];
DEMO: http://jsfiddle.net/25hBV/1/

Now a days you can do
const str = "Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$";
var result = str.split("$$").reduce(function(acc, curr) {
curr && (acc[curr] = (acc[curr] + 1) || 1);
return acc
}, {});
console.log(result);

Split the string into an array, and putting the array into an object takes care of duplicates and counts occurences as key/value pairs in the object, see fiddle!
var stringIHave = "Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$",
s = stringIHave.split('$$');
obj = {};
for (var i=s.length; i--;) {
obj[s[i]] = (s[i] in obj) ? obj[s[i]]+1 : 1;
}
// obj.Java == 8
FIDDLE

If you want it short and sweet:
// variable declarations
var arParts = stringIHave.match(/\w+/g),
result = {},
i = 0,
item;
// Copy the array to result object
while (item = arParts[i++]) result[item] = (result[item] || 0 ) + 1;
demo

Related

Take a string , evaluate it and find if there is a number and repeat part of string that number of times?

I was writing code and came into this problem,
You have a specific string which is in this form:
d ae2 n s
now we have to decode this in a specific way,
Split it into different parts by spaces to make an array like ["d","ae2","n","s"]
Evaluate each element of the array and find out if there is a number in it.
If there is a number then repeat the string the number of times.
Add it into the array and continue.
So the output array should be
["d","ae","ae","n","s"]
I have already tried a lot but got nothing
I have used this code earlier but it ends on the second string:
var str = "d ae2 n s"
var res = str.split(" ");
alert(res.length);
for(var x = 0; x < res.length; x++ ){
var std = res[x];
var fun = checkNum(std);
if(fun === true){
var numbers = str.match(/\d+/g).map(Number);
var index = res.indexOf(std);
var result = std.replace(/[0-9]/g, '');
var res2 = result.repeat(numbers);
res[index] = res2;
}
else{
continue;
}
for(var i = 0; i < res.length; i++ ){
console.log(res[x]);
}
}
function checkNum(t){
return /\d/.test(t);
}
// I am a terible coder :/
expected input : d ae2 n s
expected output : ["d","ae","ae","n","s"]
Using fill() and flatMap() methods and
regex replace
/[^0-9]/ - all non numerical chars
/[0-9]/ - all numerical chars
var str = 'd ae2 n s'
var res = str
.split(' ')
.flatMap(i =>
Array(+i.replace(/[^0-9]/g, '') || 1)
.fill(i.replace(/[0-9]/g, ''))
)
console.log(res)
You can simply loop over your array and populate an other array that will hold your result after checking for a number :
const results = [];
"d ae2 n s".split(' ').forEach(token => {
const match = token.match(/\d+/);
if (match) {
const newStr = token.split(/\d/)[0];
for (let i = 0; i < match[0]; i++) {
results.push(newStr);
}
} else {
results.push(token)
}
})
console.log(results);
You can check Seblor's answer for optimized logic. I have modified your code so that it will be easy for you to understand where you went wrong while doing this. I have added comments to your code where I have changed things:
var str = "d ae2 n s"
var res = str.split(" ");
// create a variable to store the output.
var output = [];
for(var x = 0; x < res.length; x++ ){
var std = res[x];
var fun = checkNum(std);
if(fun === true){
// map returns an array, so take the first element, it will be your number.
var numbers = str.match(/\d+/g).map(Number)[0];
var index = res.indexOf(std);
var result = std.replace(/[0-9]/g, '');
// instead of doing the repeat and updating the current index,
// push the result, i.e. the current string to be repeated "numbers" times into
// the output array.
for (var i = 0; i < numbers; i++) {
output.push(result)
}
}
else{
// if does not contain any number, push the current item to ouput
output.push (std);
continue;
}
}
function checkNum(t){
return /\d/.test(t);
}
console.log(output);
You can do:
const str1 = 'd ae2 n s';
const str2 = 'e d aefg4 m n s';
const regex = /\d+/;
const getResult = input => input.split(' ').reduce((a, c) => {
const n = c.match(regex);
return n
? [...a.concat(c.replace(n, ' ').repeat(n).trim().split(' '))]
: [...a, c];
}, []);
console.log(getResult(str1));
console.log(getResult(str2));
you can use the Array prototype reduce and filter
const input = 'd ae2 n s';
const output = input.split(' ').reduce((memory, current) => {
const numberIndex = current.split('').findIndex(c => !isNaN(c));
const newCurrent = current.split('').filter((_, index) => index !== numberIndex).join('');
if(numberIndex !== -1) {
for(let i = 0; i < parseInt(current[numberIndex]); i++) {
memory.push(newCurrent);
}
} else {
memory.push(current);
}
return memory;
}, []);
console.log(output);
Hope this helped
You can try with following:
let str = "d ae2 n s"
let split = str.split(" ")
let rx = new RegExp("[0-9]")
let res = [];
split.forEach(s => {
if(rx.exec(s) !== null) {
let rxResult = rx.exec(s)
let count = rxResult[0];
let matchIdx = rxResult[1];
for(let i = 0; i < count; i++) {
res.push(s.replace(count, ""))
}
} else {
res.push(s);
}
})

How to get the longest string in array without similar like values?

I have 2 arrays.
1: [a, ab, abc, abcde]
2: [a, ab, abc, abcde, abcdefe, axde]
in the first array, I used this code to get the longest line.
function longestChain(words) {
// Write your code here
var xintTOstring = "";
var result = 0;
for (var x = 0; x < words.length; x++){
xintTOstring = words[x].toString();
if (xintTOstring.length > result) {
result = xintTOstring.length;
}
}
return result;
}
but then in the second array, the longest is "axde". because the abcde in that array cannot be the longest because it has an equal like value.
I try this code but did not get the expected result. and also the longest line is the abcdefer.
question: how can I get the longest line and check if it is valued like equal in the string. I tried this code but did not get the right output.
function longestChain(words) {
// Write your code here
var xintTOstring = "";
var result = 0;
for (var x = 0; x < words.length; x++){
xintTOstring = words[x].toString();
if (!words[x].toString().inclcudes(xintTOstring)) {
if (xintTOstring.length > result) {
result = xintTOstring.length;
}
}
}
return result;
}
regards
function equalLike(word) {
// should the equality be checked within the array or in global stream?
}
function longestChain(words) {
return words.reduce((longest,word) => longest = longest.length > equalLike(word).length ?
longest : word,'');
}
the longest word acts as the accumulator.
If I understand correctly, each call to longest word should return the longest word not yet found. Go through each list, keep object of longest words, check against that object, and check substrings against keys
const longestWords = {};
const longestChain = function(words) {
let longestInList = "";
words.forEach(function(word) {
if (validLongestWord(word) && word.length > longestInList.length) {
longestInList = word;
}
});
longestWords[longestInList] = longestInList.length; //maybe handy for sorting later
return longestInList;
}
const validLongestWord = function(word) {
if(longestWords[word]) return false;
return !Object.keys(longestWords).some(key=>key.indexOf(word) >=0);
}
console.log(longestChain(["a", "ab", "abc", "abcde", "abcdefe", "axde"])); //abcdefe
console.log(longestChain(["a", "ab", "abc", "abcde", "abcdefe", "axde"])); //axde
console.log(longestChain(["a", "ab", "abc", "abcde", "abcdefe", "axde"])); //none
I believe this is the problem that the OP is trying to solve using JavaScript:
Longest Character Removal Chain
and
Interview Questions - String Chain
Anyone please feel welcome to edit this answer to provide a solution for the question asked.
var StackOverFlow;
(function(StackOverFlow) {
var LongestChain = (function() {
function LongestChain() {}
LongestChain.main = function(args) {
// Array of words
var words = ["a", "ab", "abc", "abcdefe", "axde"];
console.info(
"Longest Chain Length : " + LongestChain.longest_chain(words)
);
};
LongestChain.longest_chain = function(w) {
if (null == w || w.length < 1) {
return 0;
}
var maxChainLen = 0;
var words = w.slice(0).slice(0);
var wordToLongestChain = {};
for (var index7809 = 0; index7809 < w.length; index7809++) {
var word = w[index7809];
{
if (maxChainLen > word.length) {
continue;
}
var curChainLen =
LongestChain.find_chain_len(word, words, wordToLongestChain) + 1;
/* put */ wordToLongestChain[word] = curChainLen;
maxChainLen = Math.max(maxChainLen, curChainLen);
}
}
return maxChainLen;
};
LongestChain.find_chain_len = function(word, words, wordToLongestChain) {
var curChainLen = 0;
for (var i = 0; i < word.length; i++) {
var nextWord = word.substring(0, i) + word.substring(i + 1);
if (words.indexOf(nextWord) >= 0) {
if (wordToLongestChain.hasOwnProperty(nextWord)) {
curChainLen = Math.max(
curChainLen,
/* get */ (function(m, k) {
return m[k] ? m[k] : null;
})(wordToLongestChain, nextWord)
);
} else {
var nextWordChainLen = LongestChain.find_chain_len(
nextWord,
words,
wordToLongestChain
);
curChainLen = Math.max(curChainLen, nextWordChainLen + 1);
}
}
}
return curChainLen;
};
return LongestChain;
})();
StackOverFlow.LongestChain = LongestChain;
LongestChain["__class"] = "StackOverFlow.LongestChain";
})(StackOverFlow || (StackOverFlow = {}));
StackOverFlow.LongestChain.main(null);

How to find the most duplicate "values" in javascript array?

my question is actually similar to: Extracting the most duplicate value from an array in JavaScript (with jQuery)
I Found this but it always return one value only which is 200.
var arr = [100,100,200,200,200,300,300,300,400,400,400];
var counts = {}, max = 0, res;
for (var v in arr) {
counts[arr[v]] = (counts[arr[v]] || 0) + 1;
if (counts[arr[v]] > max) {
max = counts[arr[v]];
res = arr[v];
}
}
console.log(res + " occurs " + counts[res] + " times");
pls help me to return values not just one...
The result is should like this:
200,300,400
.
pls help thank you!
You have to iterate your counts to find the max occurred result.
var arr = [100,100,200,200,200,300,300,300,400,400,400];
var counts = {}, max = 0, res;
for (var v in arr) {
counts[arr[v]] = (counts[arr[v]] || 0) + 1;
if (counts[arr[v]] > max) {
max = counts[arr[v]];
res = arr[v];
}
}
var results = [];
for (var k in counts){
if (counts[k] == max){
//console.log(k + " occurs " + counts[k] + " times");
results.push(k);
}
}
console.log(results);
Create a Object iterating the arry containing the indexes of most repeated values, like below
var arr = [100,100,200,200,200,300,300,300,400,400,400];
valObj = {}, max_length = 0, rep_arr = [];
arr.forEach(function(el,i){
if(valObj.hasOwnProperty(el)){
valObj[el] += 1;
max_length = (valObj[el] > max_length) ? valObj[el] : max_length
}
else{
valObj[el] = 1;
}
});
Object.keys(valObj).forEach(function(val){
(valObj[val] >= max_length) && (rep_arr.push(val))
});
console.log(rep_arr);
After the object is created with key as array value and value as array indexes of that value, you can play/parse that. Hope this helps.
Iterating an array using for..in is not a good idea. Check this link for more information.
Hopefully below snippet will be useful
var arr = [100, 100, 200, 200, 200, 300, 300, 300, 400, 400, 400];
//Use a reduce fuction to create an object where 100,200,300
// will be keys and its value will the number of times it has
//repeated
var m = arr.reduce(function(i, v) {
if (i[v] === undefined) {
i[v] = 1
} else {
i[v] = i[v] + 1;
}
return i;
}, {});
// Now get the maximum value from that object,
//getMaxRepeated will be 3 in this case
var getMaxRepeated = Math.max(...Object.values(m));
//An array to hold elements which are repeated 'getMaxRepeated' times
var duplicateItems = [];
// now iterate that object and push the keys which are repeated
//getMaxRepeated times
for (var keys in m) {
if (m[keys] === getMaxRepeated) {
duplicateItems.push(keys)
}
}
console.log(duplicateItems)
The following would do the trick assuming that all items in arr are numbers:
//added some numbers assuming numbers are not sorted
var arr = [300,400,200,100,100,200,200,200,300,300,300,400,400,400];
var obj = arr.reduce(//reduce arr to object of: {"100":2,"200":4,"300":4,"400":4}
(o,key)=>{//key is 100,200, ... o is {"100":numberOfOccurrences,"200":numberOf...}
o[key] = (o[key])?o[key]+1:1;
return o;
},
{}
);
// obj is now: {"100":2,"200":4,"300":4,"400":4}
//create an array of [{key:100,occurs:2},{key:200,occurs:4}...
var sorted = Object.keys(obj).map(
key=>({key:parseInt(key),occurs:obj[key]})
)//sort the [{key:100,occurs:2},... by highest occurrences then lowest key
.sort(
(a,b)=>
(b.occurs-a.occurs===0)
? a.key - b.key
: b.occurs - a.occurs
);
console.log(
sorted.filter(//only the highest occurrences
item=>item.occurs===sorted[0].occurs
).map(//only the number; not the occurrences
item=>item.key
)
);
Try as following ==>
function getDuplicate( arr ){
let obj = {}, dup = [];
for(let i = 0, l = arr.length; i < l; i++){
let val = arr[i];
if( obj[val] /**[hasOwnProperty]*/ ) {
/**[is exists]*/
if(dup.find(a => a == val) ) continue;
/**[put Unique One]*/
dup.push(val);
continue;
};
/**[hold for further use]*/
obj[val] = true;
}
return dup;
};
Use ==>
getDuplicate([100,100,200,200,200,300,300,300,400,400,400]);
Try the following:
var candles = [100,100,200,200,200,300,300,300,400,400,400];
let tempArray = {}
for (let index = 0; index <= (candles.length - 1); index++) {
let valueToCompare = candles[index];
if (tempArray[valueToCompare]) {
tempArray[valueToCompare] = tempArray[valueToCompare] + 1;
} else {
tempArray[valueToCompare] = 1;
}
}
let highestValue;
Object.values(tempArray).forEach(item => {
if (highestValue === undefined) highestValue = item;
if (highestValue < item) highestValue = item;
});
console.log(highestValue);

Javascript count repeating letter

I'm new student in here,sorry for asking simple question and I'm trying to solve a problem to count a same letter.
Input:"aabbcde"
cause a = 2, b= 2, c= 1 , d =1 , e = 1
Output:"2a2b1c1d1e" or a2b2c1d1e1
and here's my code unfinished, I stucked
function repeatL(str) {
var word = str.split("").sort();
var temp = 0;
var i =1;
while(i< word.length){
if(word[i] === word[i +1]) {
//return temp to array of a += 1 ?
};
}
}
repeatL("abbbdd"); //output should be a1b3d2
also what if the input is not string but an array:
Input:[a,ab,bc,d,e]
is that even possible to solved?
You could use a variable for the result string, start with a count variable with 1 and iterate with a check of the former and actual letter. Then either count or move the count to the result set with the last letter. Reset counter to one, because the actual letter count is one.
At the end, finish the result with the last count and the letter, because one letter is not processed with the count (remember, you start with index 1, and you look always to the letter before of the actual index).
function repeatL(str) {
var word = str.split("").sort(),
count = 1,
i = 1,
result = '';
while (i < word.length) {
if (word[i - 1] === word[i]) {
count++;
} else {
result += count + word[i - 1];
count = 1;
}
i++;
}
result += count + word[i - 1];
return result;
}
console.log(repeatL("aabbcde"));
console.log(repeatL(['a', 'ab', 'bc', 'd', 'e'].join(''))); // with array after joining
You can simply use reduce() to build array and then join() to get string.
var input = "aabbcde";
var result = input.split('').reduce(function(r, e) {
var i = r.indexOf(e);
(i != -1) ? r[i - 1] ++: r.push(1, e)
return r;
}, []).join('')
console.log(result)
I'd go with an object and add each character as a key. If the key exists increment the value, else add a new key and with value 1
function repeatL(str) {
var count = {};
var arr = str.split("");
str = "";
for(var i=0;i<arr.length;i++){
if(count[arr[i]]){
count[arr[i]] = count[arr[i]]+1;
}
else {
count[arr[i]] = 1;
}
}
for(var key in count){
str+= key+count[key];
}
return str;
}
Following example also works with arrays:
function getFrequency(string) {
var freq = {};
for (var i=0; i<string.length;i++) {
var character = string[i];
if (freq[character]) {
freq[character]++;
} else {
freq[character] = 1;
}
}
return freq;
};
function repeatL(str) {
var freq = getFrequency(str);
result = '';
for (var k in freq) {
if (freq.hasOwnProperty(k)) {
result += freq[k] + k;
}
}
return result;
};
console.log(repeatL('abbbdd'));
console.log(repeatL('aabbcdeaaabbeedd'));
console.log(repeatL(['a', 'a', 'b', 'a', 'c']));

Push different object in an array with a for loop

I have an element structured like this:
Element ->
[{values: arrayOfObject, key:'name1'}, ... ,{values: arrayOfObjectN, key:'nameN'}]
arrayDiObject -> [Object1, Object2, ... , ObjectN] //N = number of lines in my CSV
Object1 -> {x,y}
I have to take data from a big string:
cityX#substanceX#cityY#substanceY#
I thought to make it this way, but it seems like it pushes always in the same array of objects. If I put oggetto = {values: arrayDateValue, key: key}; inside the d3.csv function, instead if I put outside the function it add me only empty objects.
Here is my code:
var final = new Array();
var oggetto;
var key;
function creaDati() {
var newdate;
var arrayDateValue = new Array();
var selString = aggiungiElemento().split("#");
//selString is an array with selString[0]: city, selString[1]: substance and so on..
var citySelected = "";
var substanceSelected = "";
for (var i = 0; i < selString.length - 1; i++) {
if (i % 2 === 0) {
citySelected = selString[i];
} else if (i % 2 !== 0) {
substanceSelected = selString[i];
key = citySelected + "#" + substanceSelected;
d3.csv("/CSV/" + citySelected + ".csv", function(error, dataset) {
dataset.forEach(function(d) {
arrayDateValue.push({
x: d.newdate,
y: d[substanceSelected]
});
});
});
oggetto = {
values: arrayDateValue,
key: key
};
arrayDateValue = [];
final.push(oggetto);
}
}
}
Any idea ?
First you should make the if statement for the city and then for the key, which you seem to be doing wrong since you want the pair indexes to be the keys and the not pair to be the city, and you are doing the opposite. And then you need to have the d3.csv and push the objects outside of the if statement, otherwise in your case you are just adding elements with citySelected="".
Try something like :
for(var i = 0; i < selString.length -1; i+=2){
cittySelected = selString[i];
substanceSelected = selString[i+1];
key = citySelected + "#" + substanceSelected;
d3.csv("/CSV/"+citySelected+".csv", function(error, dataset){
dataset.forEach(function(d){
arrayDateValue.push({x: d.newdate, y: d[substanceSelected]});
});
});
oggetto = {values: arrayDateValue, key: key};
arrayDateValue = [];
final.push(oggetto);
}
It's is not the best way to do it, but it is clearer that what you are following, i think.
In the if(i % 2 == 0) { citySelected = ... } and else if(i % 2 !== 0) { substanceSelected = ... } citySelected and substanceSelected will never come together.
The values should be in one statement:
if(...) { citySelected = ...; substanceSelected = ...; }
The string can be splitted into pairs
city1#substance1, city2#substance2, ...
with a regex (\w{1,}#\w{1,}#).
Empty the arrayDateValue after the if-statement.
Hint:
var str = "cityX#substanceX#cityY#substanceY#";
function createArr(str) {
var obj = {};
var result = [];
var key = "";
// '', cityX#substanceX, '', cityYsubstanceY
var pairs = str.split(/(\w{1,}#\w{1,}#)/g);
for (var i = 0; i < pairs.length; i++) {
if(i % 2 !== 0) {
key = pairs[i];
// d3 stuff to create values
obj = {
// Values created with d3 placeholder
values: [{x: "x", y: "y"}],
// Pair
key: key
};
result.push(obj);
}
// Here should be values = [];
}
return result;
}
var r = createArr(str);
console.log(r);
May be you can do like this;
var str = "cityX#substanceX#cityY#substanceY",
arr = str.split("#").reduce((p,c,i,a) => i%2 === 0 ? p.concat({city:c, key:a[i+1]}) : p,[]);
console.log(JSON.stringify(arr));
RESOLVED-
The problem is about d3.csv which is a asynchronous function, it add in the array when it finish to run all the other code.
I make an XMLHttpRequest for each csv file and it works.
Hope it helps.

Categories

Resources