trying to loop on string array but it throws error foreach is not a function what is correct way to implement using typescript ?
main.ts
content = ["renewel","payments"]
if i do for loop
for (let i = 0, len = content.length; i < len; i++) {
console.log(content[i]);
}
it prints all indexs [r e n e etc
if do foreach
content.forEach(function(content){
console.log(content);
})
it throws error content.forEach is not a function
Your code works just fine; it's very likely you've mutated content's type in some way at some point in your code. Ensure any functions you may be passing it (content) to aren't mutating the original array.
You might also consider using newer syntax, like:
content.forEach(item => {
console.log(item);
});
or even
content.forEach(item=> console.log(item));
Two small things, by the way; there's no need to cache length in a for loop (JS engine does that for you), and I don't know if it matters or not... but you've misspelled 'renewal' ;)
Related
I'm playing with an Angular app, I have a method in a service that raises an HTTP get request to JSONplaceholder, and the response is an object array with 100 posts. I was wondering how can I render only 10 out of those 100 posts, and only could think about creating an auxiliary variable and do the following:
posts:any;
modified:any[] = [];
ngOnInit(): void {
this.dataService.getPosts().subscribe( res =>
{
this.posts = res;
for (let i = 0; i < this.posts.length; i++) {
i < 10 ? this.modified.push(this.posts[i]) : void(0);
}
}
)
}
This works, but I have to iterate the modified variable in my template, and I'm pretty sure there are better ways to improve this, with a better approach. How can this little code be a little better?
Thanks
Use array.slice - the function takes two parameters, 'start' and 'end'.
'end' signifies the index after the last item that you want (it is not inclusive of the 'end' index), and is optional. If 'end' is not supplied, you will get all elements starting at end and continuing to the end of the array.
So, in your case,
modified = posts.slice(0, 10);
just concerning the for loop you can do
for ( let i=0, len=this.posts.length; i<len; i++ ){
// code
}
this way you will only run this.posts.length once (this is just in case ths.posts has lots of data)
To handle arrays you can always check the JavaScript Array docs: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array
In this case you could use the slice method:
this.modified = res.slice(0,10);
I am new to js and hope this is not too trivial, but I am unable to find any help on the net.
I wish to output to console.log and prevent moving to a new line, so the next time the output will be appended to the same line. ie,
"use strict";
for (let i = 0; i<=9;i++){
console.log(i); // here i would like to freeze the output so the result is 0123456789 on one line, rather than those digits in a column.
}
I have seen fixes involving assigning the outputs to a string and printing in 1 hit, but that seems incredibly crude. Even in Fortran 4 as I recall in the '70s, you could prevent moving to a new line before printing again, so I think I am missing something fundamental. Also I cannot find any general help on formatting numerical output in javascript. Can someone point me in the right direction?
Thanks
Unfortunately, the console.log() method will only write out a string to a single line and doesn't support the appending behavior you are looking for.
As you detailed in your original post, you could accomplish writing the final result out through the use of a variable (i.e. displaying the final concatenated string), but not continually appending to the same line within the console itself as the loop is being iterated over.
Alternative Grouping Option
The concept of grouping entries is supported, which is obviously very different than your original ask, but it may be worth considering as mentioned in the documentation for console.group() and might look something like this:
var rollingConcatenation = '';
console.group("Looping Group Example");
for (let i = 0; i<=9;i++){
rollingConcatenation += i;
console.log(rollingConcatenation);
}
console.groupEnd();
This can give your console the following appearance, which can help with readability (depending on your use cases):
Do It Yourself Implementation
Another option might be to store your current console value within a variable and at clear it and rewrite the updated values out. Depending on your very specific use cases, you could achieve the behavior you are looking for using something like this crude implementation:
// Define a custom console
var customConsole = {
// Store a reference to your backing value
tempValue: '',
// Always write out the most recent value
log: function(msg) {
this.tempValue += msg;
console.clear();
console.log(this.tempValue);
},
// A clear method to clear the backing console
clear: function() {
this.tempValue = '';
console.clear();
}
}
for (var i = 0; i < 10; i++) {
// Use your custom console instead of the normal one
customConsole.log(i);
}
Take a new variable outside the loop and then prepare that string inside the loop and then you can console.log() outside the loop.
var str = '';
for (let i = 0; i <= 9; i++) {
str += i;
}
console.log(str);
I was working on counting sort1 problem on hackerrank. I am using JavaScript to solve the problem.
Standard input is providing a number and an array which I was reading like this
var inp = input.split('\n')
var n = parseInt(inp[0]); //Number of elements
var ar = inp[1].split(' ').map(function(item){
return parseInt(item);
}); //Array of numbers.
I was using above code in almost all of my solutions, it always worked.
Then I process the above array ar in for loop which is giving runtime error in one of the test cases(last testcase).
for(var i = 0; i < n; i++) {
var number = ar[i];
//more code
}
But if I don't parse elements of the array using map function but parse them later in for loop, one by one, I don't get any error.
var ar = in[1].split(' '); //Array of numbers in string format
for(var i = 0; i < n; i++) {
var number = parseInt(ar[i]);
//more code
}
Can Anyone explain Why?
in is a keyword, and you are trying to use it as a variable. I'm not sure why it says "Runtime Error", since this is actually a parsing error. Once renamed to something else, I could run the first two paragraphs error-free.
The only problem I remember having on Hackerrank that the .split() method often gave an empty string ("") as the last element of the array. Probably that's why you failed on the last test case.
Make your logic like:
if(arr[i] !== "")
// perform operations
else
break;
Also, you can't use in as a identifier because it is a reserved keyword.
What is the best way to add the additional path information to each javascript object? Like "assets/img/upload/" before each jpg name? That I have url="assets/img/upload/02.jpg" etc.? That would be great help!
My data right now:
[Object { url="02.jpg"},
Object { url="03.jpg"},
Object { url="09.jpg"},
Object { url="04.jpg"},
Object { url="5.jpg"}
...]
A simple for loop:
for(var i = 0; i < array.length; i++)
{
array[i].url = "assets/img/upload/" + array[i].url;
}
Suppose your array of objects is called MyArray:
for (var i = 0, LoopTimes = MyArray.length; i < LoopTimes; i++) {
MyArray[i].url = "assets/img/upload/" + MyArray[i].url;
}
Note that:
a) the opening curly brace goes on the same line as the for statement. See Crokfod on Javascript The Good Parts on youtube for the explanation. In javascript, putting the opening brace on the next line can create some weird bugs that are hard to detect.
b) I cache the length of MyArray in LoopTimes so that I don't have to evaluate the length of the array at every iteration.
If you are only going to be running this code in a modern browser, you could always consider using the map method of the Array object.
Assuming your array of objects is called "array"
array.map(function(item) {return item.url = "assets/img/upload/" + item.url;});
This runs the anonymous function, that takes an "item" in the array, and returns the modified url field, over each element of the array.
If you need your code to run on older browsers, stick with the for loops suggested by the other contributors.
array.sort(function(left, right) {
return index(otherArray, left) < index(otherArray, right);
});
This is O(len(array) ^ 2) so for a reasonable size array of len = 1000 this takes constant * 1 million operations which easily overshoots the IE 5 million operators cap.
Thus IE throws a script is taking too long even though this is fast.
The problem is that IE does not have it's own Array.prototype.indexOf so I can't reduce the operation count down to O(len(array) and rely instead end up using a double for loop instead of a single for loop.
I considered array.join and using String.prototype.indexOf but the objects in the arrays are DOM elements and you can't convert them to a string (easily).
Telling IE users to remove this default cap is not an option.
I can think of two possible solutions to this problem: one of which will work everywhere, the other which is entirely IE-proprietary (and I expect doesn't work in IE9, but that supports Array.prototype.indexOf, so that's a non-issue).
The first, simpler, solution is to just set a property on each HTMLElement of the desired order and sort by that. If you care about the desired order persisting, you'll have to make sure the HTMLElement objects don't get garbage collected, so you'll have to keep references to them around (it's probably simplest to just create an array in the global scope for it).
The IE-only solution is to do something similar to what #maclema was proposing, using a lookup object, and HTMLElement.uniqueID:
var otherArrayLookup = {};
for (var i=0; i < otherArray.length; i++) {
otherArrayLookup[otherArray[i].uniqueID] = i;
}
array.sort(function(left, right) {
return otherArrayLookup[left.uniqueID] < otherArrayLookup[right.uniqueID];
});
You'll want to add some branches in there (don't put any within the callback function, but use different callback functions) for the Array.prototype.indexOf supported case, the HTMLElement.uniqueID supported case, and the none-of-the-above case.
You could try making an index lookup object. This should greatly increase performance too.
var otherArrayLookup = {};
for ( var i=0; i<otherArray.length; i++ ) {
otherArrayLookup[otherArray[i]] = i;
}
array.sort(function(left, right) {
return otherArrayLookup[left] < otherArrayLookup[right];
});