I want to add the value "peanuts" to the bag array in Java Script. Any ideas where I'm going wrong?
var bag = [];
{
for (i=0; i<bag.length; i++) {
bag.push([i] === "peanuts");
}
}
First of all you are looping over an empty array. This loop will never iterate since the array is being defined right over it without being filled before the loop.
Second, what you're pushing into the array is in fact the result of the condition [i] === "peanuts" which if it was a valid condition, will result in a boolean value.
As #Tushar said, you should use bag.push("peanuts") to add the string "peanuts" to the array bag. So let's say your code could be like this(unless you describe what kind of condition you want inside the for loop):
var bag = [];
bag.push("peanuts");
By the way, you're using an unnecessary scope block:
var bag = [];
{ // <-- Unnecessary scope block
for (i=0; i < bag.length; i++) {
bag.push([i] === "peanuts");
}
} // <-- Unnecessary scope block
Some push() examples.
This example adds peanuts to the bag array using the push command and then checks if the element is in the array using the indexOf function. This last function will return -1 if the element is not in the array, otherwise it returns the first index position the element was found at
var bag = [];
bag.push("monkeys")
bag.push("peanuts")
bag.push("bananas")
if (bag.indexOf("peanuts") >= 0) {
document.write("Found my peanuts at index " + bag.indexOf("peanuts"))
}
Related
I'm going through Chapter 4 of Eloquent JavaScript in case anyone wants to see exactly what's going on. https://eloquentjavascript.net/04_data.html.
I'm trying to understand where this For loop grabs its length value from.
for (let event of journalEvents(JOURNAL)) {
console.log(event + ":", phi(tableFor(event, JOURNAL)));
As I understand from earlier in the chapter, this For loop could also be written as:
for (let i = 0; i < journalEvents(JOURNAL).length; i++) {
let event = journalEvents(JOURNAL)[i];
console.log(event + ":", phi(tableFor(event, JOURNAL)));
}
This means the length can be found somewhere in the function journalEvents() when passed the arguement JOURNAL.
function journalEvents(journal) {
let events = [];
for (let entry of journal) {
for (let event of entry.events) {
if (!events.includes(event)) {
events.push(event);
}
}
}
return events;
}
At this point, I'm a little lost. I am guessing I need to determine the value of journalEvents(JOURNAL). Is it going to be the return value of the function?
The return value is the array events[]. Does this mean the length value is the length of events[]?
The answer is yes, the length value is that of the events array. However, length is not really a direct factor here. Arrays are iterables, so you can iterate through them with for...of loops. You can easily test this by changing the function journalEvents so that it returns a number, and see what happens :)
The function journalEvents(journal) returns an array, which is added to inside the function. Basically this is the same as putting the array that the function returns wherever you put journalEvents(journal):
for (let event of [something]) {
console.log(event + ":", phi(tableFor(event, JOURNAL)));
}
Notice that the for…of loop only would call journalEvents(JOURNAL) once, and then iterates of the result value. If you want to rewrite it to a "normal" loop, you should introduce a temporary variable for that:
const events = journalEvents(JOURNAL);
for (let i = 0; i < events.length; i++) {
const event = events[i];
console.log(event + ":", phi(tableFor(event, JOURNAL)));
}
Does this mean the length value is the length of events[]?
Yes.
I'm using a for x in loop to check if a value is == to [] and if so remove the property using remove but it just does not seem to work.
const whosOnline = (a) => {
var obj = { online:[],
offline:[],
away:[] };
for(let i = 0; i < a.length; i++){
if(a[i].lastActivity > 10 && a[i].status == 'online'){obj.away.push(a[i].username)}
else if(a[i].status == 'offline'){obj.offline.push(a[i].username)}
else{obj.online.push(a[i].username)}
}
for(let x in obj){
console.log(obj[x])
if(obj[x] === []){delete obj[x]}}
return obj
}
you were close, however you also need to reference the array index for each object key value. Comments explaining this in the code below.
var obj = { online:[],
offline:[],
away:[] };
for(var x in obj){
if(!obj[x][0]){ // The 0 is the index inside the online array, next loop it will be the offline array and then the away array.
console.log('The array is empty');
// Do what you want to do now that it is empty
// This will continue to loop through and check the value of all the keys in the object.
}
}
console.log('done');
Good luck -
Mitch from
https://spangle.com.au
Using some debugging (simply testing if a console.log gets printed for instance) you find that your if-condition is never true.
This is because you test if an array equals a newly created empty array. This can never be the case, because objects are compared by object reference instead of value.
Instead you want to probably test to see if your array is empty by doing ‘if(obj[x].length===0)’ (or shorter: ‘if(!obj[x].length)’)
I am assigning a variable, proxies, equal to an array. I am trying to add items to that array at a later point in time and then access that array in other files.
The problem is, the proxyHelper.proxies value is not updating to reflect the value of proxies variable.
After modifying the array, console.log(proxies) returns the modified array, but console.log(proxyHelper.proxies) returns a blank. I need to access the proxyHelper.proxies value in other files, so you can see why this is a problem.
I use similar code elsewhere and it works fine - what am I not seeing?
var proxies = [];
proxyHelper.proxies = proxies;
proxyHelper.tester = function(win) {
electron.ipcMain.on('saveProxies', function(event, data) {
// Clear the previous proxies from list
proxies = [];
// Split proxies based on line breaks
if (data != '') {
let proxiesList = data.split('\n');
// i<= because we want to run a check to see if all proxies are added
for (let i = 0; i <= proxiesList.length; i++) {
// if the for loop hasn't ran through all proxies
if (i + 1 <= proxiesList.length) {
proxies.push(proxiesList[i]);
}
// Once it's loop through all proxies
else {
//Returns nothing
console.log(proxyHelper.proxies);
//Returns array with added items
console.log(proxies);
win.webContents.send('goodProxies', 'Saved!');
}
}
} else {
win.webContents.send('emptyProxies', 'Empty.');
}
})
}
proxies = [];
You just assigned a new array to this variable.
proxyHelper.proxies still points to the previous value, and is not affected.
You should always use a single variable, or mutate it instead of re-assigning it.
Here is what is going on in your code:
var proxies = []; // This new variable ("proxies") contains a reference to an empty array.
proxyHelper.proxies = proxies; // You assign the same reference to a property
// (named "proxies") of the "proxyHelper"
// object. The "proxies" property points
// to the same empty array as the variable above.
proxyHelper.tester = function(win) {
electron.ipcMain.on('saveProxies', function(event, data) {
proxies = []; // You assign a new reference to the global variable
// "proxies", which points to a new empty array.
// At this point the reference assigned to
// "proxyHelper.proxies" is still the original
// empty array from line 1
// ...
}
// ...
}
So when you access "proxyHelper.proxies", you are always accessing the original empty array the has never been modified...
What you should do is:
proxyHelper.proxies = []; // resets the object's property to a new empty array
Don't need proxy variable, as its changes aren't reflected to proxyHelper.proxies
Just use proxyHelper.proxies itself
Also i've cleaned up your code a little bit
There are plenty of Array methods you can use, instead of for loop
proxyHelper.proxies = []
proxyHelper.tester = function(win) {
electron.ipcMain.on('saveProxies', function(event, data) {
//Split proxies based on line breaks
if (data != '') {
let proxiesList = data.split('\n');
proxiesList.forEach(function(proxy) {
proxyHelper.proxies.push(proxy)
})
win.webContents.send('goodProxies', 'Saved!');
} else {
win.webContents.send('emptyProxies', 'Empty.');
}
})
}
I need to parse an 80GB+ CSV file, and thought this a good opportunity to understand iterators in JavaScript (and then probably use an existing library such as csv-iterator, fast-csv, etc).
Looking at an iterator example on MDN HERE, I see this code:
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
};
}
Which is pretty self-explanatory. I can create an iterator for an array:
var iteratorForMyArray = makeIterator([1,2,3,4,5,6,7,8,9, etc])
And then I can use my shiny new iterator to 'iteratively' pull out values of my array:
var val0 = iteratorForMyArray.next().value
var val1 = iteratorForMyArray.next().value
etc
I can see why this is useful when parsing a CSV file. I'm wondering if there is any point in creating such an iterator for a simple array?
I often find that while simplified examples are useful for understanding, it's sometimes hard to see when the example is only useful as an example vs is actually useful in programming.
Because JavaScript already provides 2 mechanisms for creating iterators over array structures:
1: Basic for loop
for (let i = 0, i < [1,2,3,4,etc]; i++) {
...
}
2: Array.prototype.forEach
[1,2,3,4,etc].forEach(function(val, i, arr) {
...
})
(which I have just seen is slow on this site)
Questions:
Does my custom iterator offer anything that these iterators don't?
Do both these 'in-house' iterators create 'iterators' (i.e. what I understand as sequential pointers to values in data structures)? Or am I off by miles...
ForEach guarantees order, as well as it'll skip invalid indexes etc. Your iterator doesn't provide anything extra when compared to a standard for loop, it'll just be slower, as you're calling a function to get the next item, where a basic for loop doesn't have this overhead. Use a for loop and cache the length to start for better performance.
One good feature of iterators is that each call gets the next element, whereas forEach it's all or nothing (you can't exit early), and with both a for loop and forEach all the logic must be inside the loop.
Consider an array iterator like:
function arrayIterator(array) {
// Get array indexes as an array
var indexes = Object.keys(array)
.filter(
// Test for valid Array index property
key => key == +key && key >= 0 && key.length == String(+key).length)
// Sort as numbers
.sort(function(a, b){return a-b});
// Parameters held in closure
var current = 0;
var count = 0;
var maxCount = indexes.length;
// Return iterator function
return function() {
return ++count > maxCount? 'done' : array[indexes[current++]];
};
}
var arr = [0,1,,,4,5,6];
// Add non-index numeric property
arr['01'] = '01';
// Add indexable numeric property
arr['10'] = '10';
// Add some other property
arr.foo = 'foo';
var x = arrayIterator(arr);
console.log(x()); // 0
console.log(x()); // 1
console.log(x()); // 4
console.log(x()); // 5
console.log(x()); // 6
console.log(x()); // 10
console.log(x()); // 'done'
console.log(x()); // 'done'
I'm sure there's more to be done in regard to checking valid indexes and also testing that an index still exists when the iterator is called, but is shows the concept.
There also needs to be some documentation about what happens when the array is modified between calls.
I dont want to push duplicate values into selectedOwners, so in below code user is selecting owner if owner already existed in selectedOwners array i dont want to push , How can i check that to avoid duplicate values in an array ?
ctrl.js
var selectedOwners = [];
$scope.addProcessOwner = function(dataItem){
var selectedOwner = {
fullName: dataItem.fullName,
workerKey: dataItem.workerKey
}
if(selectedOwners.indexOf(selectedOwner) !== -1) {
selectedOwners.push(selectedOwner);
}
console.log('WORKER DATA',selectedOwners);
}
You can use Array.prototype.some method
The some() method tests whether some element in the array passes the test implemented by the provided function.
var isExists = function(e) {
if (e.fullName == selectedOwner.fullName
&& e.workerKey == selectedOwner.workerKey) {
return true;
}
}
if (!selectedOwners.some(isExists)) {
selectedOwners.push(selectedOwner);
}
The use of Array.indexOf is obvious for simple types like strings and numbers.
However, when you are looking for an object, you have to pass the exact same object. A different object with all the same properties and values will still not work. Think of the array as containing pointers to the objects and you must look for the same pointer.
Instead you will need to write your own method to compare the owners for equality and loop through the array doing this check.
Try wrapping your "if" logic in a for-loop .
Example
//Following code loops through array and check for already existing value
for(var i = 0; i < selectedOwners.length; i++){
if(selectedOwners.indexOf(selectedOwner) !== -1) {
selectedOwners.push(selectedOwner);
}
}