0

I have a list of strings, I want to check if the string contains a specific word, and if it does split all the words in the string and add it to an associative array.

myString = ['RT @Arsenal: Waiting for the international', 'We’re hungry for revenge @_nachomonreal on Saturday\'s match and aiming for a strong finish']
wordtoFind = ['@Arsenal'] 

I want to loop through the wordtoFind and if it is in myString, split up myString into individual words and create an object like

newWord = {@Arsenal:[{RT:1},{Waiting:1},{for:1},{the:1},{international:1}]}
for(z=0; z <wordtoFind.length; z++){
 for ( i = 0 ; i < myString.length; i++) {
 if (myString[i].indexOf(wordtoFind[z].key) > -1){
 myString[i].split(" ")
 }
 }
}
Paul Roub
36.5k27 gold badges88 silver badges95 bronze badges
asked Mar 31, 2016 at 11:28
8
  • 3
    your newWord is not a valid object. Commented Mar 31, 2016 at 11:30
  • Can you clarify? I don't understand what you want to create. Effectively, the objet is not valid (what are the keys or {waiting:1}, {for:1}, etc. ? And you want all the words into objects like {word:1}? Can you explain? Commented Mar 31, 2016 at 11:34
  • So you want to count each of the words in your string? Commented Mar 31, 2016 at 11:37
  • @NinaScholz I have edited the question, is this a valid object ? Commented Mar 31, 2016 at 11:56
  • @Vincent sorry I am new to javascript but what i want is the main key is wordtoFind which maps onto the words in newWord and their occurrence in myString Commented Mar 31, 2016 at 11:57

4 Answers 4

2

I would say something likes would work, this also counts the amount of occurrences of a word in a sentence. JavaScript does not have associative arrays like PHP for instance. They just have objects or numbered arrays:

var myString = ['RT @Arsenal: Waiting for the international', 'We’re hungry for revenge @_nachomonreal on Saturday\'s match and aiming for a strong finish'];
var wordtoFind = ['@Arsenal'];
var result = {};
for(var i = 0, l = wordtoFind.length; i < l; i++) {
 for(var ii = 0, ll = myString.length; ii < ll; ii++) {
 if(myString[ii].indexOf(wordtoFind[i]) !== -1) {
 var split = myString[ii].split(' ');
 var resultpart = {};
 for(var iii = 0, lll = split.length; iii < lll; iii++) {
 if(split[iii] !== wordtoFind[i]) {
 if(!resultpart.hasOwnProperty(split[iii])) {
 resultpart[split[iii]] = 0;
 }
 resultpart[split[iii]]++;
 }
 }
 result[wordtoFind[i]] = resultpart;
 }
 }
}
console.log(result); 
//{"@Arsenal":{"RT":1,"Waiting":1,"for":1,"the":1,"international":1}}
answered Mar 31, 2016 at 11:40
Sign up to request clarification or add additional context in comments.

5 Comments

thanks for this but I got a comment saying that result was not a valid object. I have now edited the question, how would this change the answer? Thanks @PierreDuc
@qwertyayyy Is there a reason you want it to be an array? My answer generates a valid object as well. If you check the output from the console.log you can see what it is. It would change my answer in such a way that it makes it harder (but not impossible) to count for the amount of occurrences
@PierreDuuc Sorry I am new to Javascript and I just got a comment saying it was an invalid object that all. But thank you for the answer
@qwertyayyy Well, in that case, i am sure that my answer will suffice your needs :)
how do I access individual elements in the result object ? Thanks
1

This method makes use of the forEach-function and callbacks. The containsWord-function was left with a for-loop for now to reduce some callbacks, this can obviously be changed.

var myString = [
 'RT @Arsenal: Waiting for the international',
 'We’re hungry for revenge @_nachomonreal on Saturday\'s match and aiming for a strong finish',
 '@Arsenal: one two three four two four three four three four'
];
var wordtoFind = ['@Arsenal'];
// define the preprocessor that is used before the equality check
function preprocessor(word) {
 return word.replace(':', '');
}
function findOccurences(array, search, callback, preprocessor) {
 var result = {};
 var count = 0;
 // calculate the maximum iterations
 var max = search.length * array.length;
 // iterate the search strings that should be matched
 search.forEach(function(needle) {
 // iterate the array of strings that should be searched in
 array.forEach(function(haystack) {
 if (containsWord(haystack, needle, preprocessor)) {
 var words = haystack.split(' ');
 // iterate every word to count the occurences and write them to the result
 words.forEach(function(word) {
 countOccurence(result, needle, word);
 })
 }
 count++;
 // once every iteration finished, call the callback
 if (count == max) {
 callback && callback(result);
 }
 });
 });
}
function containsWord(haystack, needle, preprocessor) {
 var words = haystack.split(' ');
 for (var i = 0; i < words.length; i++) {
 var word = words[i];
 // preprocess a word before it's compared
 if (preprocessor) {
 word = preprocessor(word);
 }
 // if it matches return true
 if (word === needle) {
 return true;
 }
 }
 return false;
}
function countOccurence(result, key, word) {
 // add array to object if it doesn't exist yet
 if (!result.hasOwnProperty(key)) {
 result[key] = [];
 }
 var entry = result[key];
 // set the count to 0 if it doesn't exist yet
 if (!entry.hasOwnProperty(word)) {
 entry[word] = 0;
 }
 entry[word]++;
}
// call our function to find the occurences
findOccurences(myString, wordtoFind, function(result) {
 // do something with the result
 console.log(result);
}, preprocessor);
// output:
/*
 { '@Arsenal':
 [ RT: 1,
 '@Arsenal:': 2,
 Waiting: 1,
 for: 1,
 the: 1,
 international: 1,
 one: 1,
 two: 2,
 three: 3,
 four: 4 ] }
 */

Feel free to ask any questions, if the answer needs clarification.

I hope this fits your needs.

answered Mar 31, 2016 at 14:23

2 Comments

You took it to the next level ;). But a little remark though, forEach is not an asynchronous function.
@PierreDuc correct, I haven't been using this too much lately, it's blocking obviously. Also thanks for the edit to the english documentation, haven't even noticed that google led me to the german version. ;)
0

You're on the right track. You just need to store the split string into the associative array variable.

var assocArr = [];
for(z=0; z <wordtoFind.length; z++){
 for ( i = 0 ; i < myString.length; i++) {
 if (myString[i].indexOf(wordtoFind[z]) > -1){
 myString[i].split(" ").forEach(function(word){
 assocArr.push(word);
 });
 }
 }
}
answered Mar 31, 2016 at 11:38

2 Comments

the .key is not working in the if statement - use it like this: if (myString[i].indexOf(wordtoFind[z]) > -1){.....
Thanks. That's what I get for copy pasting I guess :/
0

I think the key problem that stuck you is the data structure. The optimal structure should be something like this:

{
 @Arsenal:[
 {RT:1, Waiting:1, for:1, the:1, international:1},
 {xxx:1, yyy:1, zzz:3}, //for there are multiple ones in 'myString' that contain the same '@Arsenal'
 {slkj:1, sldjfl:2, lsdkjf:1} //maybe more
 ]
 someOtherWord:[
 {},
 {},
 ....
 ]
}

And the code:

var result = {};
//This function will return an object like {RT:1, Waiting:1, for:1, the:1, international:1}.
function calculateCount(string, key) {
 var wordCounts = {};
 string.split(" ").forEach(function (word) {
 if (word !== key) {
 if (wordCounts[word] === undefined) wordCounts[word] = 1;
 else wordCounts[word]++;
 }
 });
 return wordCounts;
}
//For each 'word to find' and each string that contain the 'word to find', push in that returned object {RT:1, Waiting:1, for:1, the:1, international:1}.
wordToFind.forEach(function (word) {
 var current = result[word] = [];
 myString.forEach(function (str) {
 if (str.indexOf(word) > -1) {
 current.push(
 calculateCount(str, word)
 );
 }
 }); //Missed the right parenthesis here
});
answered Mar 31, 2016 at 12:07

6 Comments

Hi I am getting a syntax error from the statement "continue" @Yan-Yang
@qwertyayyy I'm sorry. I made a mistake. I modified the code and it's ok now. continue can't be used in forEach. Here is a question about that: stackoverflow.com/questions/31016841/…
Im sorry but how do I output this to the console. It just returning an empty list. @Yan-Yang
I missed a right parenthesis just now. I have added it. And I used wordToFind not wordtoFind. Also, to output to the console, use console.dir(result);.
I have tested in my console using your example of myString and wordtoFind. The result is @Arsenal: Array[1] [ 0: Object {@Arsenal:: 1, RT: 1, Waiting: 1, for: 1, international: 1, the: 1}]
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.