I'm new to Javascript and I am begining to learn.
I need help understanding; how can I retrieve each carachter of this array.
var possibleRaysPasswords =['mobleyAndTrentonAreDead','tyrellIsElliot','dreadPirateRoberts'];
Like in these example:
e.g: femtocell
f
fe
fem
femt
femto
femtoc
femtoce
femtocel
femtocell
Much appreciated.
If you want to get each character of each element, you may do a simple array transformation to get you an array of all the characters in all the items:
var allOfThem = arr.join('').split('');
That is: you first join all the elements into a single string. and then you split this string into array of characters. Then you can loop over it.
Can you provide an example of what you've tried so far? Doing so will help us to answer any confusion you have.
For a start, let's demonstrate how to loop through each element in the array. We can declare an array the way you demonstrated:
var myArray = ["elements", "are", "pretty", "cool! "];
To loop through this array, we can simply use a for loop.
for (var i = 0; i < myArray.length; ++i) {
console.log(myArray[i]); // this provides the element at the ith index of the array
}
This will log, in order:
elements
are
pretty
cool!
You can access the individual characters of a string in the same exact way that you access individual elements of an array. Try that and see if you can get to where you need to be.
You could use two nested loop, one for the array and one for the atrings for the letters in combination with String#slice
var possibleRaysPasswords =['mobleyAndTrentonAreDead','tyrellIsElliot','dreadPirateRoberts'],
i, j;
for (i = 0; i < possibleRaysPasswords.length; i++) {
for (j = 1; j <= possibleRaysPasswords[i].length; j++) {
console.log(possibleRaysPasswords[i].slice(0, j));
}
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
Let me know if something is unclear. The comments in the code should tell you what's going on though:
// making this a constant, because we only want to read from this data
const passwords = ['mobleyAndTrentonAreDead', 'tyrellIsElliot', 'dreadPirateRoberts'];
// somewhat recently, we can also define functions like this
const printPassword = password => {
// this function prints out the password starting from the first character, all the way to its end
// if the password is 'test', the output should be 't te tes test'
let resultString = ''; // this will be returned later
// let's use the good old for loop
// start at the first character (zero-indexed), and use the counter variable i to mark the end of the substring
for (let i=1; i <= password.length; i++) {
resultString += password.substring(0, i) + ' ';
}
return resultString;
};
// iterating over every password in the passwords array,
// and log the returned string to the console
passwords.forEach(password => console.log(printPassword(password)));
user 'forEach' to iterate elements of array and 'substr' to part of string:
var possibleRaysPasswords =['mobleyAndTrentonAreDead','tyrellIsElliot','dreadPirateRoberts'];
possibleRaysPasswords.forEach(function(element){
for(var i=0 ; i<element.length ; i++){
console.log(element.substr(0,i));
}
});
'for of' can also be used for iteration:
for (element of possibleRaysPasswords){
for(var i=0 ; i<element.length ; i++){
console.log(element.substr(0,i));
}
}
As simple as that:
var letters = [];
for(let i of possibleRaysPasswords ){letters.push.apply(letters,i.split(""))}
console.log(letters);
That will create and array with all letters. Not sure if that was the question though
Related
I am creating a program that involves removing text from an array. If a letter is included in a word in the array, then that word will be removed. My first test was successful, a simple regular expression with a small array:
var regex = /z/;
var words = ["eggs", "zebras", "lampshade"];
for (i = 0; i < words.length; i++) {
let testResult = regex.test(words[i]);
if (!testResult) {
words.splice(i, 1);
}
}
console.log(words);
As expected, it returned [ 'zebras' ]. Because this was successful, I quickly scaled up using an npm package called "an-array-of-english-words". I ran my new script:
const masterWords = require("an-array-of-english-words");
var regex = /z/;
var words = masterWords;
for (i = 0; i < words.length; i++) {
let testResult = regex.test(words[i]);
if (!testResult) {
words.splice(i, 1);
}
}
console.log(words);
Every time I run it it ends up returning values that do not abide by the regular expression. For example, the code above returned ['aa', 'aahed', 'aahs', ...] as its first few values. Do I have to change my code to deal with a bigger array? Am I making a stupid mistake I didn't notice?
I think it may be due to the fact that you are splicing the array and looping it at the same time.
For ex. if the length of array is 5 and the current index is 2, after splicing the array, the item at the index 3 will be moved to the index 2, and will be skipped in the next iteration, since the next index will be 3.
So, you can create a clone of the words and change it, while iterating the original array.
#Joey , in official documentation if you see , try using it this way as a workaround . Also #Igor Moraru's answer explains why the issue might be happening.
console.log(words.filter(d => /z/.test(d)))
I have seen several answers on Stackoverflow but none have helped me. I have a huge array of nearly 100,000 words, of which I am trying to remove all words that contain a number. I am using the following to do that:
for(var i = 0; i < words.length; i++){
if (hasNumbers(words[i]) {
words.splice(i, 1);
}
function hasNumbers(t)
{ return /\d/.test(t); }
It seems to work, but not all the time because I am still getting words that contain numbers. What can I change to make this remove all words that contain any number at all?
(I am using p5.js with my js)
That is because when you delete a word at index i, the next word will have index i, yet you still increase i, thereby skipping a word which you never inspect.
To solve this you can go backwards through your array:
for(var i = words.length - 1; i >= 0; i--){
// etc.
Here is a shorter way to remove words with digits:
words = words.filter(a => !hasNumbers(a));
Finally, you really should call your second function hasDigits instead of hasNumbers. The words "digit" and "number" have a slightly different meaning.
Here is a snippet, using ES6 syntax, that defines the opposite function hasNoDigits and applies it to some sample data:
let words = ['abcd', 'ab0d', '4444', '-)#', '&9ยต*'];
let hasNoDigits = s => /^\D*$/.test(s);
console.log(words.filter(hasNoDigits));
words = words.filter(a => !hasNumbers(a));
I had started writing this and then trincot answered. His answer is correct, though with the popular and widespread usage of ES5 array functions, I feel like you could simplify this down quite a bit.
window.addEventListener('load', function() {
var data = [
'w3.org',
'google.com',
'00011118.com'
]; //This is supposed to be your data, I didn't have it so I made it up.
var no_nums = data.filter(function(item) {
//Tests each string against the regex, inverts the value (false becomes true, true becomes false)
return !/\d/.test(item);
});
var results = document.getElementById('results');
no_nums.forEach(function(item) {
results.innerHTML += item + '<br />';
//Loops through each of our new array to add the item so we can see it.
});
});
<div id="results">
</div>
I'm pulling my hair out over this one. I have two arrays, likes & dislikes, both filled with about 50 strings each.
I also have a JSON object, data.results, which contains about 50 objects, each with an _id parameter.
I'm trying to check find all the objects within data.results that aren't in both likes and dislikes.
Here's my code at present:
var newResults = []
for(var i = 0; i<data.results.length; i++){
for(var x = 0; x<likes.length; x++){
if(!(data.results[i]._id == likes[x])){
for(var y = 0; y<dislikes.length; y++){
if(!(data.results[i]._id == dislikes[y])){
newResults.push(data.results[i]);
console.log("pushed " + data.results[i]._id);
}
else
{
console.log("They already HATE " + data.results[i]._id + " foo!"); //temp
}
}
}
else
{
console.log(data.results[i]._id + " is already liked!"); //temp
}
}
}
As you can see, I'm iterating through all the data.results objects. Then I check whether their _id is in likes. If it isn't, I check whether it's in dislikes. Then if it still isn't, I push it to newResults.
As you might expect by looking at it, this code currently pushes the result into my array once for each iteration, so i end up with a massive array of like 600 objects.
What's the good, simple way to achieve this?
for (var i = 0; i < data.results.length; i++) {
isInLiked = (likes.indexOf(data.results[i]) > -1);
isInHated = (dislikes.indexOf(data.results[i]) > -1);
if (!isInLiked && !isInHated) {
etc...
}
}
When checking whether an Array contains an element, Array.prototype.indexOf (which is ECMAScript 5, but shimmable for older browsers), comes in handy.
Even more when combined with the bitwise NOT operator ~ and a cast to a Boolean !
Lets take a look how this could work.
Array.prototype.indexOf returns -1 if an Element is not found.
Applying a ~ to -1 gives us 0, applying an ! to a 0 gives us true.
So !~[...].indexOf (var) gives us a Boolean represantation, of whether an Element is NOT in an Array. The other way round !!~[...].indexOf (var) would yield true if an Element was found.
Let's wrap this logic in a contains function, to simply reuse it.
function contains (array,element) {
return !!~array.indexOf (element);
}
Now we only need an logical AND && to combine the output, of your 2 arrays, passed to the contains function.
var likes = ["a","b","f"] //your likes
var dislikes = ["c","g","h"] //your dislikes
var result = ["a","c","d","e","f"]; //the result containing the strings
var newresult = []; //the new result you want the strings which are NOT in likes or dislikes, being pushed to
for (var i = 0,j;j=result[i++];) //iterate over the results array
if (!contains(likes,j) && !contains (dislikes,j)) //check if it is NOT in likes AND NOT in dislikes
newresult.push (j) //if so, push it to the newresult array.
console.log (newresult) // ["d","e"]
Here is a Fiddle
Edit notes:
1. Added an contains function, as #Scott suggested
Use likes.indexOf(data.results[i]._id) and dislikes.indexOf(data.results[i]._id).
if (likes.indexOf(data.results[i]._id) != -1)
{
// they like it :D
}
Try first creating an array of common strings between likes and dislikes
var commonStrAry=[];
for(var i = 0; i<likes.length; i++){
for(var j=0; j<dislikes.length; j++){
if(likes[i] === dislikes[j]){
commonStrAry.push(likes[i] );
}
}
}
then you can use this to check against data.results and just remove the elements that don't match.
I have a JSON response like this:
var errorLog = "[[\"comp\",\"Please add company name!\"],
[\"zip\",\"Please add zip code!\"],
...
Which I'm deserializing like this:
var log = jQuery.parseJSON(errorLog);
Now I can access elements like this:
log[1][1] > "Please add company name"
Question:
If I have the first value comp, is there a way to directly get the 2nd value by doing:
log[comp][1]
without looping through the whole array.
Thanks for help!
No. Unless the 'value' of the first array (maybe I should say, the first dimension, or the first row), is also it's key. That is, unless it is something like this:
log = {
'comp': 'Please add a company name'
.
.
.
}
Now, log['comp'] or log.comp is legal.
There are two was to do this, but neither avoids a loop. The first is to loop through the array each time you access the items:
var val = '';
for (var i = 0; i < errorLog.length; i++) {
if (errorLog[i][0] === "comp") {
val = errorLog[i][1];
break;
}
}
The other would be to work your array into an object and access it with object notation.
var errors = {};
for (var i = 0; i < errorLog.length; i++) {
errors[errorLog[i][0]] = errorLog[i][1];
}
You could then access the relevant value with errors.comp.
If you're only looking once, the first option is probably better. If you may look more than once, it's probably best to use the second system since (a) you only need to do the loop once, which is more efficient, (b) you don't repeat yourself with the looping code, (c) it's immediately obvious what you're trying to do.
No matter what you are going to loop through the array somehow even it is obscured for you a bit by tools like jQuery.
You could create an object from the array as has been suggested like this:
var objLookup = function(arr, search) {
var o = {}, i, l, first, second;
for (i=0, l=arr.length; i<l; i++) {
first = arr[i][0]; // These variables are for convenience and readability.
second = arr[i][1]; // The function could be rewritten without them.
o[first] = second;
}
return o[search];
}
But the faster solution would be to just loop through the array and return the value as soon as it is found:
var indexLookup = function(arr, search){
var index = -1, i, l;
for (i = 0, l = arr.length; i<l; i++) {
if (arr[i][0] === search) return arr[i][1];
}
return undefined;
}
You could then just use these functions like this in your code so that you don't have to have the looping in the middle of all your code:
var log = [
["comp","Please add company name!"],
["zip","Please add zip code!"]
];
objLookup(log, "zip"); // Please add zip code!
indexLookup(log, "comp"); // Please add company name!
Here is a jsfiddle that shows these in use.
Have you looked at jQuery's grep or inArray method?
See this discussion
Are there any jquery features to query multi-dimensional arrays in a similar fashion to the DOM?
Here is my code:
var divarray = document.getElementById("yui-main").getElementsByTagName("div");
var articleHTML;
var absHTML;
var keyHTML;
var bodyHTML = [];
for( var i in divarray) {
if(divarray[i].className == "articleBody"){
articleHTML = divarray[i];
for( var j in articleHTML ){
bodyHTML[i] = '';
if(articleHTML[j].className == "issueMiniFeature"){continue;}
if(articleHTML[j].className == "abstract"){absHTML = articleHTML[i]; continue;}
if(articleHTML[j].className == "journalKeywords"){keyHTML = articleHTML[i]; continue;}
bodyHTML[i] = articleHTML[i];
}
break;
}
i++;
}
The error I am getting is:
SyntaxError: Unexpected token var
I am using Google Chrome
The javascript for...in doesn't do what you would expect (which is enumerate through eleemnts in an array.
for...in in javascript will enumerate through the key/value pairs (or public variables) that make up the object (which isn't what you want).
You need to use a good, old fashioned for loop.
You can add this to your script:
Array.prototype.foreach = function (callback) {
for (var i=0; i < this.length; i++) {
callback(this[i]);
}
}
Then you simply do this:
myarray.foreach(function (currentItem) {
/*...do whatever with the currentItem...*/
});
I think you mistaking JavaScript for the functionality of PHP. JavaScript does not have foreach loops. JavaScript has for in, which is what you are incorrectly using and normal for loops. Use a standard for loop when dealing with arrays. You will need to use a for in loop with object literals because the index is not the simplicity of an incrementing positive integer.
In JavaScript a for loop has 3 parts in its argument separated by a semicolon as follows:
* start position of incrementor (optional if the variable is previous defined with 0 or a positive integer)
* end position of incrementor
* method of incrementation
In the following examples arrayName is value I made up for the name of an array:
for (; a < arrayName.length; a += 1) {
for (a = x + 1; a < arrayName.length + 3; a += 2) {
The for in loop argument has two required parts and a third part to prevent errors using an if condition:
* The value of an index to search for
* The name of the container in which to search
* The third part is an if condition
The following example will return the value supplied to the "book" index of the objectName object literal. objectName is a name I made for an example object literal:
for ("book" in objectName) {
if (objectName.hasProperty("book")) {
Why not use a traditional for loop instead? You're not really using an associative array here ...
That's not the right way to iterate over a collection.
You want a standard for loop, not a for..in loop
for( var i = 0, l = divarray.length; i < l; i++ ) {
There's something else, you then proceed to try to iterate over each element
for( var j in articleHTML ){
articleHTML at this point holds a reference to a single HTML node - not a collection or array of any sort.