How to select certain Index in Array?
Hello,
Let’s say for example I have an array such as:
let sample = [“5”,”+”,”6”];
How would I be able to add these together based on the operator? (Could be -, +, /, *)
I’m assuming I’ll have to loop through Array, find the first operator, then go back an index and add to the index after the operator?
159 Replies
Assuming the array is always going to be a simple binomial expression, then you already know the operation is at index 1. But as this is still a string, you need to have a switch statement or some other mechanism to convert it into an valid JavaScript expression:
If it's a bit more complicated than than, for example
5 + 6 * 2
then you have to recursively apply this same method, such that you are always evaluating a binomial expression (left and right side). The tricky part comes when you need to do some operations with higher priority.What if the array was with multiple operations? I figured I would need to set up an additional array (with all operation types, +, -, *, /), check the expression array for an operation, then do the corresponding operation based on the number before & after the operation type in the array
Would I check for the operator index then do ++ to the index, grab the number, then do — and grab that number and handle the expression?
That's the tricky part, indeed. What you are describing sounds a whole lot like an actual code interpreter which is how things like programming languages are transformed from a simple string of text to meaningful tokens. At least that's the only way I know how to, but I'm sure there are a bunch of different clever ways.
If you want to go the simple route of using nothing but arrays as you are doing right now, the difficult part is determine the operator precedence.
I might be asking bad questions, but my end result is trying to make a calculator. I’m new to JS & haven’t read any solutions. Trying to do this from scratch with what I think may work
No, not at all. You are most definitely on the right track. But making an interpreter is something I would reserve for later on. For now, I agree trying to stick to the basics is best.
To be honest, I've never tried it this route myself either.
I could be over / under complicating, Idek. Just giving it a go. I have the basic infrastructure made, now it’s just about handling the expressions
Is there anyway else you could recommend me going about this, maybe without an array? I don’t think I’ll be able to handle complicated equations just looking to do simple stuff for now
So far, this is what I have but it doesn't account for operator precedence:
Just curious. Switch vs If statements. What’s the difference?
Is using Switch for something like this more practical since there’s specified “cases” ie operations
Very little, it's basically a simpler way to write a lot of
if
statements.Okay makes sense
In this case, for example, it could be useful since there may be ways of writing the same operations. For example, multiplication could be: *, x or ^. In this case you could write it simply like:
That would be similar to using || in an If?
Yes, exactly.
But to me at least this is much cleaner.
Okay cool thanks I appreciate the explanation. I’ll upload my code pen later tonight and show what I have for a calculator
Now I'm curious too...
When I did a calculator a while back I converted from infix "3 + 4" to postfix "+ 3 4" format for which there is a standard algorithm. It handles things like order of operations and parentheses and whatnot.
Postfix is much easier to solve programatically. You go right to left. If an entry is a number you push it on a stack. If an entry is an operator you pop the appropriate number of operands off the stack and push the result back on.
At the end you should have one thing left on the stack: the answer.
Yes, definitely. I also did it once using a similar approach with an interpreter and that gives you the most flexibility so you can construct really complex expressions.
With just the basic structures you can also do it but it gets complicated quickly, even without accounting for parenthesis and such.
@-Matt So I was curious how to implement this and it's definitely doable, but not all that intuitive, and the more operators you want to support the more complex it becomes. Although I think it's a great exercise anyway. If you need help let me know, I've been able to come up with something that supports the basic operations and parenthesis. It's not pretty, and I'm sure there are plenty of ways to make it more efficient, but it works.
For reference I wrote some test at the end of the file and these all pass:
Interesting
I honestly wrote something completely different. I’ll post it shortly here
These are just the tests to prove that it works, and how you'd use it.
I'm curious to see how you did it, please share when it's done! 👍
this is a good situation to use "eval" in
or, use a function
I'm stuck on trying to handle larger expressions. Currently, it's able to do the math for single expression, such as 1+1, 2x2, 4/2, etc
I'm still new to JavaScript and I'm trying to just tackle projects to learn. My method for doing this might not be the right way, but if you guys can please give me some constructive critism.
What I was trying to do is:
Get the sum after two number inputs, track the first operator input, do math, then reset and add any additional numbers and operators to the equation.
@joao6246@epic2937@dysbulic
what i would do is to write a function that does the work for me, using the `new Function("return [...]") or something like that
Sorry, I'm a bit confused
so, you have an array that's in the format
[Number, String, Number]
, right?I separated the operator and numbers into separate Arrays
It should be an array with strings (that I convert to number to calculate) and variable with operator
what do you actually have?
all you've shown, so far, was this, which is in the format i said before
Here
This is the codepen with the code I wrote
I wrote things differently because I couldn’t figure out a solution with my original thoughts
so, what's the problem with the code?
it seems to work fine
I don’t know how to handle larger expressions
Such as 5+5-10
10*20-2, etc
you don't
in the place of the first value, you put the result of the last expression
so, instead of calculating
10*20-2
, you calculate 10*20
and then 200-2
which is exactly how it's working right nowI believe just the calculation function is where I’m going wrong because of checking first two index, when Adding a 3rd number leaves a missing index
I should put the total as the first index
Is my solution for this sort of project the wrong way to go about it?
honestly, it's a simple calculator
and while you're not doing it the most optimal super mega ultimately perfectly perfect, it's working
Hmm okay. I appreciate your input.
if you want a proper code review, i can give you one
the use of global variables is a very bad idea
you're manipulating html instead of using an input, which allows you to type a number
the ui could be re-written to be entirely event-driven with a single event in a form, instead of 16 click events on the buttons
instead of manipulating HTML
should I do something like:
expression.setAttribute('value', number);
and change expression to be an input field rather div?no, if it is an input, you can do
expression.value = 'new value'
is it better practice in this instance to avoid using innerHTML?
well, in this case, it doesn't matter
Trying to understand when you say not to use global variables here. Do you mean variables that can be used across entire scope, or ones that are grabbing data such as innerHTML
but using
innerHTML
causes a redraw on the entire element, and all the ccontents are thrown away and the browser has to re-parse and re-calculate the new styles for what you're setting
if you change the value of an input, there's no html re-parsing and a lot less of work needs to be done
but honestly, in this case, it doesn't matterah so, there could be an instance where there's latency due to browser having to reprocess HTML?
it's a simple calculator that does calculator stuff
no, latency is network-related
yeah, I'm not gonna go to crazy optimizing. I'm using this example to understand context for future problems
it's just nitpicky stuff
in this case, how do you delete a number?
imagine i wanted to type 69 but typed 690
I added the functionality for clearing entire expression but not specific numbers
which is fine, but if you have an input, this is something you get for free
thats true
i guess people could delete at will and then just process whatever their entry is
instead of based on each button click
that works too
if you don't mind me asking
what's the difference between
and
but if you think about how a calculator works, it has these features:
- numbers
- period
- addition
- subtraction
- multiplication
- division
- equals sign
- clear button
- clear everything button
one's a for loop, the other is a foreach, and you don't have to index anything in the buttons with the foreach
also, it's a lot more readable to use the foreach, instead of the for loop
ahh okay. So you can't reference a specific index with foreach?
basically just loops an entire array where you can do specific checks of items without being able to re-reference them by index?
basically, yes
you do get the index as the 2nd argument
and the array as the 3rd argument
however, im not sure if you have access to array-like objects in the 3rd argument, like a node list
for (let i = 0; i < btns.length; i++) {
}
forEach(element, index, btns) {
}
I ran a test to see how forEach would output and when I put in the array as the argument, it outputted each entry in array as expected. Just curious, how does it know when to do element, index, and array arguments?
What if you wanted to specify just index and array, or element and array, etc.
Does it assume if an argument is defined as an array within scope that its the array argument?
i don't understand your question
Array.prototype.forEach() - JavaScript | MDN
The forEach() method of Array instances executes a provided function once
for each array element.
I'm reading the mozille doc right now trying to understand the parameters
that's a method of the
Array
prototype
it takes a functionAhh, so it would be ?
like this:
some array-like objects support this too
for example, doing
document.querySelectorAll()
returns a NodeList
which is an array-like object (has a length
property and increasing elements from 0 to length - 1
)that makes more sense
I'm sorry for bugging you with all these questions
NodeList & Arrays are treated the same, just NodeList are composed of elements from the document?
it's fine, we all learn by asking and trying
not exactly
but both expose a
forEach
method that you can use
i think it also supports `for(var x of NodeList) {...}´ but i'm not sureOkay cool, im going to read more about this to fully understand the differences
Thank you again for answering my questions
I really appreciate it
I'm gonna re-write my solution for this calculator and incorporate some of your feedback as well 👍
don't just take my input: take others' as well
I've just re-implemented this, in a different way:
it allows to add, divide, multiply and subtract, plus will repeat the last operation if you keep pressing
=
it's ugly, but this is just a concept
in this case, if you do 5+10
, and then you keep pressing =
, it does 15+10
, 25+10
, 35+10
...
oh, and if you click c
more than once, it clears everything, like a real calculatorCool! Thank you. I actually was curious how to implement a switch vs if
Just wondering, is considered good practice to use var over let?
depends on what you want to do
I've read something somewhere where var is suppose to be retired
why would they do that?
isnt var = let?
var
, let
and const
are slightly different
var
is available in all the scopes inside the current scope
and it does get outside scope blocksin your example
button can be used outside of the event listener?
because it's declared as var rather than let?
here's a big difference
all
x = 4
are inside a scope blockHmm okay that makes sense
is it bad practice to use let in global scope?
honestly, i wouldn't put anything in a global scope
maybe just const?
nothing
everything in the global scope will be assigned to the
window
object, in a browser
meaning, it's a global variable now
since you're handling elements, you can add the important functionality inside the onload
event
or on the onready
eventthis, for example, has variables in global scope
would you restructure to have inside of the submit listener
or like youre saying now, have an additional function outside to run script when document is loaded?
in this case, it's lazyness from me, since i was just churning out the concept inside a jsfiddle
everything wrapped in an
onload
or onready
event
it depends on what you want, but any is fineOkay, that's good to note. Thanks for letting me know
just trying to make sense of everything 👍 really appreciate your feedback
you're welcome
by the way, don't take my version as gospel
it's just a re-implementation of what you wrote, in a different way
I'm in the middle of rewriting, but taking some of your comments & suggestions into account. It's awesome to be able to see another solution to see how things could be done differently
What's the fun in that? The whole point of writing a calculator is that you come up with that logic yourself 🙂
that's the fun way of doing it, not the easy way
Exactly, that's the point! The world doesn't need more calculators, we do it for fun and learning 🤓
i did it mostly to show that you can write it in a simplified way, without touching arrays and stuff
i mean, with my implementation, it would be just another
switch
block that does nothing newYeah. Thanks again for feedback I really do appreciate it. Honestly, I’ve been trying to learn JS on and off for 10+ years now… lol
well, the best way to learn is by doing it
On and off of course, could never really stick to it. I remember being like 8 doing stuff with Jquery lol
jquery is still pretty useful
browsers are a huge mess
yeah, you can do a lot of stuff with just typescript, but it's still a messy mess
Typescript is just a spin off of JS right
Well, mmhhh I disagree with that
Microsofts JS?
no, it's a superset
imagine typescript as being a buffed up javascript
yeah, you can do a lot of stuff with just typescript, but it's still a messy messJavaScript alone is standardized and all browser support most features. Only a few things are move verbose, which you can hide away with a few functions.
It’s basically an extension to JS?
no, it's a superset
it's something on top of javascript
all javascript is valid typescript, but not all typescript is valid javascript
Is this your final version or did you improve it since you wrote it?
Hmm good to know for future. Def won’t be touching it anytime soon
I’m working on another version now outside of codepen, I’ll upload it in about a half hour or so
you kinda should, if you can
I need to learn about these different types of functions tbh
Asyn and some of the other stuff are quiet confusing to me
Yes, don't worry about TypeScript.
async? oh boy...
Lol
async/await is just promises in a coat
an async function returns a promise, but the await forces the code to wait until the promise is resolved
So it’s a function that waits for result to proceed ?
So maybe in context, if you call API with async it won’t proceed until api returns data?
or until you get an error
but, it's a pain to write anything that's async and use await
i just give up and use promises
but then, my code looks no better than having a callback chain
Promise - JavaScript | MDN
The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
Reading this makes my head go ^ lol
well, it's very simple
a promise takes a function that you execute, to do some work
that function receives 2 arguments: a function to fulfill and another function to reject the promise
for example, if you do a calculation and it returns something unexpected, you can just run the 2nd argument, or throw an exception
you then use the
then
method, which accepts a function that receives 1 parameter, which is the data that was sent from the fulfill function
you can chain those, and each then
will get the updated data
at the end of all the then
s, you can have a catch
method, which acts like a catch(exception){...}
blockHere’s an example on Mozilla
The examples Mozilla gives usually just confuse me. I kindve understand the way you’re explaining but it doesn’t make sense how they present it
they present it a bit differently
If the first .then is true and promise is fulfilled, what’s suppose to happen?
that question doesn't make sense
in essense, you're asking "if i arrive at my destination, how do i turn my car on at home?"
If it’s the fulfilled case, what’s the output in that example?
The resolve foo?
if the function
resolve
is called, it executes the function handleFulfilledA
, passed on the first then
this isnt calling it though, just declaring ?
or myPromise.then is a call?
this should make more sense than any explanation i can give
I'm going to read more about this, I'm still pretty confused (no offense to your explanation, just feels abstract rn)
and you can manipulate the data, which is passed to the next
.then
Maybe it's best to open a separate thread for this?
a common pattern is
fetch(...).then((response) => response.json).then((data) => ...)
yes, good ideaIt would also help @-Matt to receive an explanation when he runs into an actual issue, rather than examples without context
this makes more sense
Yeah sorry my bad
I've been hammering a lot of questions unrelated to this thread haha
I only say it for your own benefit, trying to learn too much at once doesn't work very well most of the time (maybe it does for you)
Honestly, it doesn't, hence the 10+ year plus of trying to learn hahaha
im the exception to that, since i learned scss, javascript es6, typescript and blade at the same time
Well JS has changed a lot in that time so maybe you just arrived at a bad time
but usually, small baby steps is best
I don't think I've ever seen stuff like promises before
Yes, always baby steps and before you know it you'll be running
they are kinda recent, but not a lot
🙏
Maybe you saw XMLHttpRequest?
I tried using this when I was playing around with APIs in node
yeah, don't think that node has that
i think it only uses ´fetch`
ohh it looked familiar
i could be wrong
It's just the old way of doing things. Better use fetch, but don't worry about those things yet just make sure you nail down the basics trust me.
How did you guys learn? Are there any good doc competitors to mozilla?
yeah,
fetch
is a lot easier to use
by doing, and working with it
and not really
even node's documentation is awful, in my opinionI vaguely read some of it when I was writing a simple Discord bot
there's w3cschools or whatever it is called, but it isn't as complete as mdn
I avoid w3 just because they use inline js*
that's a very bad take, not gonna lie
inline javascript has an huge advantage: you shave a single network request, which can be as high as 2-3 seconds saved
also, it's an easy way to have extra information available to a script that loads later
That's true, I guess from a learning perspective it's just messier
Can I send you a friend request?
please don't, lets keep it here
nothing personal against you
Np, just wanted to send you one haha
i don't mind if you @ me here, if you need help or something
I'll just leave this here in case it helps with some ideas. It's definitely not perfect, only the basic functions with a few obvious bugs. But I think it's good enough, let me know if it helps!
https://codepen.io/D10f/pen/XWoMJZE