Searching an array for a substring in Javascript - javascript

I have searched across the web though have not had any luck in correcting my issue. What I want to do is search an array for a substring and return the result. An example of the array is like this:
the_array = ["PP: com.package.id, NN: Package Name","PP: com.another.id, NN: Another Name"];
What I want to do is search the_array for com.package.id making sure that it appears between the "PP:" and ",". Also please note that the array will contain several thousand values. Hope you can help, thank you.

Easy way:
the_array.join("|").indexOf([str]) >= 0;
Other ways would be to loop thru the array using .each() or a simple for loop
Array.prototype.each = function(callback){
for (var i = 0; i < this.length; i++){
callback(this[i]);
}
}
the_array.each(function(elem){
console.log(elem.indexOf('<searchString goes here>'));
});

Related

Index Variable Rendering as Literal and Not as Value When Looping Event Listener Adds

Fellow Stackers.
I am attempting the following:
for(let i = 0; i <= promoObj.length - 1; i++) {
document.getElementById(promoObj[i]["note"]).addEventListener("click",
function(){
onPromoView(promoObj[i])
}, false);
}
promoObj is an object containing several arrays. i is the index of each array. When I run the loop shown above, onPromoView(promoObj[i] is rendered literally as onPromoView(promoObj[i] and not with the looped index number such as onPromoView(promoObj[0].
How do I get the event listener to render with the actual index number? I've tried many ways and did much searching but nothing is working. Hopefully, someone here has the answer.
BTW, I prefer the solution in vanilla JS.
Thanks.
Rudy

In an array of strings, how can I print the first element x number of times, and then print the second element x number of times, and so on?

For example:
myArray = ["Dave", "Tom", "Pete"];
I would like to print each element in myArray 3 times in the following format:
Dave
Dave
Dave
Tom
Tom
Tom
Pete
Pete
Pete
forEach loops (at least on their own) don't seem to handle what I'm trying to do. I'm going back and forth between different array and string methods but I feel there's a combination I'm missing. Any help would be appreciated. Thanks.
All you really need to do here is have two nested for loops. The first one looping through your array of strings; the second loop contains whatever mechanism you want to use for "printing" your strings. I have two variables here, one being your array, and the second a simple x to choose how many times you want your string printed.
In addition, as the comment above said, this isn't a code writing service. Next time you really need to give an example of what you did that didn't work, and asked a question based on that. A forEach loop should actually work just fine as well.
let myArray = ["Dave", "Tom", "Pete"];
let x = 3;
for (let i = 0; i < myArray.length; i++) {
for (let j = 0; j < x.length; j++) {
// whatever printing mechanism you would like goes here. let's make some html
let element = document.createElement('p');
element.textContent = myArray[i];
document.body.appendChild(element);
}
}
If you want to do something "x times" for every element, that's exactly what you should do: "for every element": "do ... x times"
["Dave", "Tom", "Pete"].forEach((e) => {
for (let i = 0; i < 3; i++) console.log(e);
});

Delete two redundant symbols from each element of a string array

I think this question should be an easy one. I use a regex expression which, actually is:
str_pow = str_input.match(/(?:x)[^][+-]?\d{1,4}\s/g);
The problem lays in that I need only numbers, though they're still of string type(don't think about this), but not this part x^. Currently the how str_pow looks like is this
This means two things: I've to either edit my regex mask, or to find a way to cut the first two "x^" characters of for each element i of the array. Can you help me to do this, because I tried to slice but it was an unsuccessful experiment.
You can loop the array:
var a = ["x^5 ", "x^4 ", "x^2 ", "x^1 "];
for(var i = 0; i< a.length; i++) {
a[i] = parseInt(a[i].substring(2, a[i].length).trim(), 10);
}
console.log(a);

Randomize Keyword Links

I'm currently looking for a method to display five keywords/links at a time from a total of about 50 at random. So for example, a function to grab a keyword and the links to go with them at random, and have them display in a webpage according to what I prefer with CSS.
It sounds simple enough but I just can't seem to find the answer I'm looking for. Any help is appreciated! Thanks!
Something like that?
function getRandomLinks(count,links){
var randomlinks = [];
for(var i = 0; i < count; i++){
randomlinks.push(links.splice(Math.floor(Math.random()*links.length),1)[0]);
}
return randomlinks;
}
console.log(getRandomLinks(2,["link1","link2","link3","link4"]));

What's the best way to loop through a set of elements in JavaScript?

In the past and with most my current projects I tend to use a for loop like this:
var elements = document.getElementsByTagName('div');
for (var i=0; i<elements.length; i++) {
doSomething(elements[i]);
}
I've heard that using a "reverse while" loop is quicker but I have no real way to confirm this:
var elements = document.getElementsByTagName('div'),
length = elements.length;
while(length--) {
doSomething(elements[length]);
}
What is considered as best practice when it comes to looping though elements in JavaScript, or any array for that matter?
Here's a nice form of a loop I often use. You create the iterated variable from the for statement and you don't need to check the length property, which can be expensive specially when iterating through a NodeList. However, you must be careful, you can't use it if any of the values in array could be "falsy". In practice, I only use it when iterating over an array of objects that does not contain nulls (like a NodeList). But I love its syntactic sugar.
var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];
for (var i=0, item; item = list[i]; i++) {
// Look no need to do list[i] in the body of the loop
console.log("Looping: index ", i, "item" + item);
}
Note that this can also be used to loop backwards.
var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];
for (var i = list.length - 1, item; item = list[i]; i--) {
console.log("Looping: index ", i, "item", item);
}
ES6 Update
for...of gives you the name but not the index, available since ES6
for (const item of list) {
console.log("Looping: index ", "Sorry!!!", "item" + item);
}
Note that in some cases, you need to loop in reverse order (but then you can use i-- too).
For example somebody wanted to use the new getElementsByClassName function to loop on elements of a given class and change this class. He found that only one out of two elements was changed (in FF3).
That's because the function returns a live NodeList, which thus reflects the changes in the Dom tree. Walking the list in reverse order avoided this issue.
var menus = document.getElementsByClassName("style2");
for (var i = menus.length - 1; i >= 0; i--)
{
menus[i].className = "style1";
}
In increasing index progression, when we ask the index 1, FF inspects the Dom and skips the first item with style2, which is the 2nd of the original Dom, thus it returns the 3rd initial item!
I like doing:
var menu = document.getElementsByTagName('div');
for (var i = 0; menu[i]; i++) {
...
}
There is no call to the length of the array on every iteration.
I had a very similar problem earlier with document.getElementsByClassName(). I didn't know what a nodelist was at the time.
var elements = document.getElementsByTagName('div');
for (var i=0; i<elements.length; i++) {
doSomething(elements[i]);
}
My issue was that I expected that elements would be an array, but it isn't. The nodelist Document.getElementsByTagName() returns is iterable, but you can't call array.prototype methods on it.
You can however populate an array with nodelist elements like this:
var myElements = [];
for (var i=0; i<myNodeList.length; i++) {
var element = myNodeList[i];
myElements.push(element);
};
After that you can feel free to call .innerHTML or .style or something on the elements of your array.
At the risk of getting yelled at, i would get a javascript helper library like jquery or prototype they encapsulate the logic in nice methods - both have an .each method/iterator to do it - and they both strive to make it cross-browser compatible
EDIT: This answer was posted in 2008. Today much better constructs exist. This particular case could be solved with a .forEach.
I think using the first form is probably the way to go, since it's probably by far the most common loop structure in the known universe, and since I don't believe the reverse loop saves you any time in reality (still doing an increment/decrement and a comparison on each iteration).
Code that is recognizable and readable to others is definitely a good thing.
I too advise to use the simple way (KISS !-)
-- but some optimization could be found, namely not to test the length of an array more than once:
var elements = document.getElementsByTagName('div');
for (var i=0, im=elements.length; im>i; i++) {
doSomething(elements[i]);
}
Also see my comment on Andrew Hedges' test ...
I just tried to run a test to compare a simple iteration, the optimization I introduced and the reverse do/while, where the elements in an array was tested in every loop.
And alas, no surprise, the three browsers I tested had very different results, though the optimized simple iteration was fastest in all !-)
Test:
An array with 500,000 elements build outside the real test, for every iteration the value of the specific array-element is revealed.
Test run 10 times.
IE6:
Results:
Simple: 984,922,937,984,891,907,906,891,906,906
Average: 923.40 ms.
Optimized: 766,766,844,797,750,750,765,765,766,766
Average: 773.50 ms.
Reverse do/while: 3375,1328,1516,1344,1375,1406,1688,1344,1297,1265
Average: 1593.80 ms. (Note one especially awkward result)
Opera 9.52:
Results:
Simple: 344,343,344,359,343,359,344,359,359,359
Average: 351.30 ms.
Optimized: 281,297,297,297,297,281,281,297,281,281
Average: 289.00 ms
Reverse do/while: 391,407,391,391,500,407,407,406,406,406
Average: 411.20 ms.
FireFox 3.0.1:
Results:
Simple: 278,251,259,245,243,242,259,246,247,256
Average: 252.60 ms.
Optimized: 267,222,223,226,223,230,221,231,224,230
Average: 229.70 ms.
Reverse do/while: 414,381,389,383,388,389,381,387,400,379
Average: 389.10 ms.
Form of loop provided by Juan Mendez is very useful and practical,
I changed it a little bit, so that now it works with - false, null, zero and empty strings too.
var items = [
true,
false,
null,
0,
""
];
for(var i = 0, item; (item = items[i]) !== undefined; i++)
{
console.log("Index: " + i + "; Value: " + item);
}
I know that you don't want to hear that, but: I consider the best practice is the most readable in this case. As long as the loop is not counting from here to the moon, the performance-gain will not be uhge enough.
I know this question is old -- but here's another, extremely simple solution ...
var elements = Array.from(document.querySelectorAll("div"));
Then it can be used like any, standard array.
I prefer the for loop as it's more readable. Looping from length to 0 would be more efficient than looping from 0 to length. And using a reversed while loop is more efficient than a foor loop as you said. I don't have the link to the page with comparison results anymore but I remember that the difference varied on different browsers. For some browser the reversed while loop was twice as fast. However it makes no difference if you're looping "small" arrays. In your example case the length of elements will be "small"
I think you have two alternatives. For dom elements such as jQuery and like frameworks give you a good method of iteration. The second approach is the for loop.
I like to use a TreeWalker if the set of elements are children of a root node.

Categories

Resources