I have an array like this {A1,B5,C6,A2,B7,C4};
I want to loop through the array and find the matching element and then do some manipulation in that match.
The match in the above array is A1 and A2, B5 and B7 and finally C6 and C4.
Below is what I have done so far:
var arr = {A1,B5,C6,A2,B7,C4};
for (i=0; i < arr.length/2; i++) // Only running till length/2 since there is always another match hence don't need to run through all the length probably
{
for (j=i+1; j < arr.length; j++)
{
if(arr[i].charAt(0) == arr[j].charAt(0))
{
j=arr.length; //This is done to end the inner loop
Do something;
//if the matching element is found, ideally the i loop should ignore this record. I don't know how to do this.
}
}
}
You will need to sort the array first to make it easier to find the matching pairs. Here is one way you can modify your code.
var arr = ['A1','B5','C6','A2','B7','C4']
arr.sort();
console.log("Sorted array : " + arr);
for (i=0; i < arr.length -1; i++) // Only running till length/2 since there is always another match hence don't need to run through all the length probably
{
if(arr[i].charAt(0) == arr[i+1].charAt(0))
{
j=arr.length; //This is done to end the inner loop
console.log("Match found : " + arr[i].charAt(0));
//if the matching element is found, ideally the i loop should ignore this record. I don't know how to do this.
}
}
You could create an object with all the matches, like so:
var arr = ['A1','B5','C6','A2','B7','C4'];
var setsOfMatches = {};
arr.forEach(function(currentItem) {
var firstLetter = [currentItem.charAt(0)];
if (setsOfMatches[firstLetter]) { //If we have a set for this letter already
setsOfMatches[firstLetter].push(currentItem); //Add this item to it
} else {
setsOfMatches[firstLetter] = [currentItem]; //Create the set
}
});
//console.log(setsOfMatches);
//{
// A:["A1","A2"],
// B:["B5","B7"],
// C:["C6","C4"]
//}
//Iterate through the sets of matches
for (var set in setsOfMatches) {
console.log("Set " + set + ": " + setsOfMatches[set]);
}
Related
This seems like a stupidly simple thing to do, but I can't figure out what I'm doing wrong. The goal is to have an array of 8 other arrays, which each contain hands of cards (in the example, the arrays just contain arbitrary numbers). Then, depending on whether passDirection is set to -1 or 1, each array is cycled through and replaced with the one next to it. The desired end result is that the values of playerList essentially shift by 1 either up or down, and this can be repeated several times without issue.
What's actually happening with the code I have below, though, is that all the arrays are just being replaced with what's at index 0, except for the first one. How can I fix this?
var playerList = new Array;
var passDirection = -1;
for(i = 0; i < 8; i++) {
playerList.push([playerList.length,i]); // Fill Arrays with arbitrary data
}
for (i=0; i< playerList.length; i++) {
console.log(i + ": " + playerList[i]); // Check their values before anything is done to them
}
for(q=0; q < 5; q++){ // Repeat the process 5 times, just because.
var bufferArray = playerList[0]; // Put Array Element 0's value in a buffer as it will be replaced first
for(i = 0; i < playerList.length && i > (playerList.length * -1); i += passDirection) {
var catcher = i; // 'catcher' should be the array that gets replaced
var passer = catcher - passDirection; // 'passer' should be the one it gets replaced with
if (catcher < 0) {
catcher = catcher + playerList.length;
}
if (passer < 0) {
passer = passer + playerList.length;
} else if (passer >= playerList.length) {
passer = passer - playerList.length;
}
if (passer == 0) {
playerList[catcher] = bufferArray;
} else {
playerList[catcher] = playerList[passer];
}
}
for (i=0; i< playerList.length; i++) {
console.log(i + ": " + playerList[i]);
}
console.log("...");
}
https://jsfiddle.net/3r1Lhwc5
You have two errors in your code:
if (passer = 0) is performing an assignment. You need if (passer === 0).
The passer index is looking at the wrong side of the value. Currently you are first getting from 1 and putting at 0, then getting from 0 and putting at 7 (i.e. -1). Notice how you are moving the same value in the second iteration. You need to change passer = catcher - passDirection to passer = catcher + passDirection
Note that all this can be done much easier with the splice, shift, unshift, pop and push Array methods (on the main playerList).
You can make your life easier by using Array methods to move elements from the beginning to end of an array or vice versa. Using this in the body of your for loop should do the trick:
if (passDirection === -1) {
const first = playerList.shift();
playerList.push(first);
}
else {
const last = playerList.pop();
playerList.unshift(last);
}
I'm working on some codewars problems and I came to this 'remove noise thing', I guess the point is to escape backslash \ and use replace method, which was easy. But I didn't want to use replace, instead I found myself in trouble trying to remove items with splice method.
Funny thing is, when I debug in Chrome dev tools, step by step I see items get removed, but console.log spits out certain characters($/·|ªl) problematic to remove, and at the end gets returned and join with those characters. Why is that?
function removeNoise(str) {
var base = "%$&/#·#|º\ª";
var arr = str.split('');
for(var i = 0; i < arr.length; i++) {
var item = arr[i];
var condition = base.indexOf(item);
if(condition + 1) {
//works like a charm
//arr[i] = '';
arr.splice(i,1);
//this thing wont work
//when debugging it removes the items from the array
//console log print no removing
}
}
return arr.join('');
}
removeNoise('he%$&/#·#|º\ª\llo'); //=> $/·|ªllo
You're using splice to remove entries from your array, but you're then incrementing i for the next loop. If you remove the entry at index 5 from a 10-entry array, what was the entry at index 6 is now at index 5 (of what's now a 9-entry array), so you don't want to increment your index.
The solution is to use a while loop and only update i if you don't splice:
function removeNoise(str) {
var base = "%$&/#·#|º\ª";
var arr = str.split('');
var i = 0;
while (i < arr.length) {
var item = arr[i];
var condition = base.indexOf(item);
if (condition + 1) {
// Remove this entry, reuse same value for 'i'
arr.splice(i,1);
} else {
// Don't remove this entry, move to next
++i;
}
}
return arr.join('');
}
var result = removeNoise('he%$&/#·#|º\ª\llo');
var pre = document.createElement('pre');
pre.appendChild(
document.createTextNode(result)
);
document.body.appendChild(pre);
You're removing characters from your array. This will throw your indexer variable i out of sync with the characters you want to test. Easy way to fix is to start at the end of the array working your way to the beginning.
Change your for loop to this.
for(var i = arr.length -; i <= 0; i--) {
function removeNoise(str) {
var base = "%$&/#·#|º\ª";
var arr = str.split('');
for(var i = arr.length - 1; i <= 0 ; i--) {
var item = arr[i];
if(base.indexOf(item) >= 0) {
//remove the offending character
arr.splice(i,1);
}
}
return arr.join('');
}
removeNoise('he%$&/#·#|º\ª\llo'); //=> $/·|ªllo
Ok so I am trying to access each individual number in the strings inside of this array.
var array = ['818-625-9945','999-992-1313','888-222-2222','999-123-1245'];
var str = "";
for (i=0; i<array.length; i++) {
str = array[i];
}
The problem is that this is the output: '999-992-1313'
and not the first element array[0]: '818-625-9945'
When I try doing a nested for loop to go through each element inside the string I am having trouble stating those elements.
var array = ['818-625-9945','999-992-1313','888-222-2222','999-123-1245'];
for (i=0; i<array.length; i++) {
for (j=0; j<array[i].length; j++) {
console.log(array[i][j]);
}
}
I do not know how to access each individual number inside of the string array[i]. I would like to find a way to make a counter such that if I encounter the number '8' I add 8 to the total score, so I can take the sum of each individual string element and see which number has the highest sum.
var array = ['818-625-9945','999-992-1313','888-222-2222','999-123-1245'];
for (i=0; i<array.length; i++) {
for (j=0; j<array[i].length; j++) {
if (array[i](j).indexOf('8') !== -1) {
// add one to total score
// then find a way to increase the index to the next index (might need help here also please)
}
}
}
Mabe this works for you. It utilized Array.prototype.reduce(), Array.prototype.map() and String.prototype.split().
This proposal literates through the given array and splits every string and then filter the gotten array with a check for '8'. The returned array is taken as count and added to the return value from the former iteration of reduce - and returned.
var array = ['818-625-9945', '999-992-1313', '888-222-2222', '999-123-1245'],
score = array.reduce(function (r, a) {
return r + a.split('').filter(function (b) { return b === '8'; }).length;
}, 0);
document.write('Score: ' + score);
A suggested approach with counting all '8' on every string:
var array = ['818-625-9945', '999-992-1313', '888-222-2222', '999-123-1245'],
score = array.map(function (a) {
return a.split('').filter(function (b) { return b === '8'; }).length;
});
document.write('Score: ' + score);
Actually rereading your question gave me a better idea of what you want. You simply want to count and retrieve the number of 8's per string and which index in your array conforms with this maximum 8 value. This function retrieves the index where the value was found in the array, how many times 8 was found and what is the string value for this result. (or returns an empty object in case you give in an empty array)
This you could easily do with:
'use strict';
var array = ['818-625-9945', '999-992-1313', '888-222-2222', '999-123-1245'];
function getHighestEightCountFromArray(arr) {
var max = 0,
result = {};
if (arr && arr.forEach) {
arr.forEach(function(value, idx) {
var cnt = value.split('8').length;
if (max < cnt) {
// found more nr 8 in this section (nl: cnt - 1)
max = cnt;
// store the value that gave this max
result = {
count: cnt - 1,
value: value,
index: idx
};
}
});
}
return result;
}
console.log(getHighestEightCountFromArray(array));
The only thing here is that when an equal amount of counts is found, it will still use the first one found, here you could decide which "maximum"
should be preferred(first one in the array, or the newest / latest one in the array)
OLD
I'm not sure which sums you are missing, but you could do it in the following way.
There I first loop over all the items in the array, then I use the String.prototype.split function to split the single array items into an array which would then contain ['818', '625', '9945']. Then for each value you can repeat the same style, nl: Split the value you are receiving and then loop over all single values. Those then get convert to a number by using Number.parseInt an then all the values are counted together.
There are definitelly shorter ways, but this is a way how you could do it
'use strict';
var array = ['818-625-9945','999-992-1313','888-222-2222','999-123-1245'],
sumPerIndex = [],
totalSum = 0;
array.forEach(function(item, idx) {
var values = item.split('-'), subArray = [], itemSum = 0;
values.forEach(function(value) {
var singleItems = value.split(''),
charSum = 0;
singleItems.forEach(function(char) {
charSum += parseInt(char);
});
itemSum += charSum;
subArray.push(charSum);
console.log('Sum for chars of ' + value + ' = ' + charSum);
});
sumPerIndex.push(subArray);
totalSum += itemSum;
console.log('Sum for single values of ' + item + ' = ' + itemSum);
});
console.log('Total sum of all elements: ' + totalSum);
console.log('All invidual sums', sumPerIndex);
I'm attempting to teach myself javascript. I chose something I assumed was simple, but ran into problems relatively quickly.
I'm attempting to search a string for another string given by the user.
My code so far is:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = [];
var one = 0;
var two = 0;
var k = 0;
var sourceSearch = function(text) {
for(i = 0; i < source.length; i++) { //for each character in the source
if(source[i] === searchString[0]) { //if a character in source matches the first element in the users input
one = source.indexOf(i); //confused from here on
for(p = searchString.length; p > 0; p--) {
}
}
}
};
sourceSearch(searchString);
My idea was:
check to see if the first loop finds a character that matches the first character in the user input
if it matches, check to see if the next X characters after the first match the next X characters in the source string
if they all match, push them to the hits array
My problem: I have no idea how to iterate along the arrays without nesting quite a few if statements, and even then, that wouldn't be sufficient, considering I want the program to work with any input.
Any ideas would be helpful. Thanks very much in advance.
Note: There are a few un-used variables from ideas I was testing, but I couldn't make them work.
You can try:
if (source.indexOf(searchString) !== -1) {
// Match!
}
else
{
//No Match!
}
As the other answers so far point out, JavaScript strings have an indexOf function that does what you want. If you want to see how it's done "by hand", you can modify your function like this:
var sourceSearch = function(text) {
var i, j, ok; // always declare your local variables. globals are evil!
// for each start position
for(i = 0; i < source.length; i++) {
ok = true;
// check for a match
for (j = searchString.length - 1; ok && j >= 0; --j) {
ok = source[i + j] === searchString[j];
}
if (ok) {
// searchString found starting at index i in source
}
}
};
This function will find all positions in source at which searchString was found. (Of course, you could break out of the loop on the first success.) The logic is to use the outer loop to advance to each candidate start position in source and use the inner loop to test whether that position actually is the position of a match to searchString.
This is not the best algorithm for searching strings. The built-in algorithm is much faster (both because it is a better algorithm and because it is native code).
to follow your approach, you can just play with 2 indexes:
var sourceSearch = function(text) {
j = 0;
for(i = 0; i < source.length; i++) {
if(source[i] === text[j]) {
j++;
} else {
j = 0;
}
if (j == text.length) {
console.log(i - j); //this prints the starting index of the matching substring
}
}
};
These answers are all pretty good, but I'd probably opt for something like this:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = source.split(searchString);
var hitsCount = hits.length - 1;
This way you have all of the data you need to figure out where each hit occurred in he source, if that's important to you.
So i am having issues coming up with an undefined array element.
1) cant get my undefined array to work
2) i want it to output the array as an occurrence of the word and number of times.
var wordCount =[];
splitAT.sort();
alert(splitAT);
for (var i = 0; i < splitAT.length; i++)
{
if(splitAT[i] in wordCount)
{
wordCount.push(1);
}
else
{
wordCount[splitAT[i]] = 1;
}
document.write('[' + splitAT[i] + '][' + wordCount[i] + ']<br>')
alert("your next wordcount is");
alert(wordCount); // this is just so i know where i am in the program.
alert("END");
First up, use the right tool for the job: wordCount should be an object rather than an array:
var wordCount = {}; // note, curly brackets
...because you plan to access it using strings as keys, not numeric array indices. (Yes, an array will work for this purpose, but it's not an array's intended purpose.)
Then in your loop, if the current word is already in wordCount you want to add 1 to the existing value, not use .push(1) which will insert a new array element at the end of the numerically indexed elements.
// WRONG:
wordCount.push(1); // inserts a new element
// RIGHT:
wordCount[splitAT[i]]++; // increments the current value
Putting that together, you would count the words like this:
var wordCount = {};
splitAT.sort();
for (var i = 0; i < splitAT.length; i++) {
if(splitAT[i] in wordCount) {
wordCount[splitAT[i]]++;
} else {
wordCount[splitAT[i]] = 1;
}
}
"i want it to output the array as an occurrence of the word and number of times."
To output the results you could do something like this:
var output = [];
for (var k in wordCount)
output.push("'" + k + "' appears " + wordCount[k] + " time(s).");
document.getElementById("NumCount").value = output.join("\n");
(Assuming you want to output to a textarea element with id="NumCount", which is what you had in your fiddle.)