Reputation: 159
var ctr;
var lst = ["", "xml", "w1", "w2"];
var ids = [];
ctr = 0;
for (y = 0; y < lst.length; y++) {
if (lst[y].substring(0, 1) === "w") {
ids[y] = lst[y];
ctr = ctr + 1;
}
}
console.log([ids, ctr]);
OUTPUT: [[undefined, undefined, 'w1','w2'], 2]
EXPECTED OUTPUT: [['w1','w2'],2]
What am I doing wrong? The counter returned the number I have expected but why am i getting 2 undefined in my list? Why is this happening?
Upvotes: 1
Views: 1707
Reputation: 2772
You can just use a filter to get the items you want and maybe use the output array length to know how many items you have after filtering the original array.
var newArr = ["", "xml", "w1", "w2"].filter(function(x) {
x.substring(0, 1) === 'w');
};
console.log([newArr, newArr.length]); // [["w1", "w2"], 2]
Upvotes: 4
Reputation: 1
Using existing js
, try substituting ctr
for y
inside if
statement
var ctr;
var lst = ["", "xml", "w1", "w2"];
var ids = [];
ctr = 0;
for (y = 0; y < lst.length; y++) {
if (lst[y].substring(0, 1) === "w") {
ids[ctr] = lst[y];
ctr = ctr + 1;
}
}
console.log([ids, ctr]);
alternatively , using Array.prototype.toString()
, String.prototype.match()
var lst = ["", "xml", "w1", "w2"]
, ids = lst.toString().match(/w./g);
console.log(ids);
Upvotes: 1
Reputation: 3940
If you want to take a different approach, using reduce will also work:
var res = lst.reduce(function(prevVal, curVal){
if (curVal.substring(0, 1) === "w") {
prevVal[0].push(curVal);
prevVal[1] = prevVal[1] + 1;
}
return prevVal;
}, [[], 0]);
console.log(res); //--> [['w1', 'w2'], 2]
I recommend it simply because avoiding for loops whenever possible makes for much more maintainable code, especially in Javascript where the vars used in the for loop condition itself are still members of the parent scope (i.e. they're accessible throughout the entire containing function, with a value of undefined given to them until the initialization value is given in the for loop).
Also, it prevents you from having to juggle index values in your head, and instead concentrate on what the loop is actually doing.
(My above example definitely could be cleaner, but it should give you an idea)
Upvotes: 1
Reputation: 3803
var lst = ["", "xml", "w1", "w2"];
var result = lst.reduce(function (x, y) {
if (y.substring(0, 1) === 'w') {
x[0] || (x[0] = []);
x[0].push(y);
x[1]++ || (x[1] = 1);
}
return x;
}, []);
console.log(result) // [["w1","w2"],2]
The result will be same as required, interesting to note here i use null coalescing notation ||
more info about it here
Suggested by @FelixKing
changing the accumulator
lst.reduce(function (x, y) {
if (y.substring(0, 1) === 'w') {
x[0].push(y);
x[1]++;
}
return x;
}, [[], 0]);
Upvotes: 2
Reputation: 388406
You need to use ids.push(lst[y]);
instead of ids[y] = lst[y];
, otherwise you will be assigning values to the ids
array at random indexes - ie missing some index values.
In your code the values are assigned at indexes 2 and 3 missing indexes 0 and 1 causing the said output, it is because you are not assigning values to ids
in all iterations - you are skipping some iterations based on the condition
Upvotes: 5