Loop through Two Arrays (JS)
I have two arrays which I'm trying to loop through to determine if they have matching values. Here is a portion of the code:
When I run the comparison, it returns no match, despite there being a match (see screenshot). What am I doing wrong here?
202 Replies
Also, what is the best way to asynchronously run this check (get result without continuing). I do have this inside of an async function, but don't know where to put an await... is it better to use for, of, instead of forEach?
can you show the data? or some sample that reproduces the problem you have?
from looking at the little code you've shown, i will say that you're comparing strings to numbers
That's the issue
Thank you
Visually it didn't seem different but it was the data type
if i were you, i would do something different
What would you recommend
i would use a set instead of an array
then you can just do
set.has(<value>)
Basically, I'm building a system that gets data from a shopify API then checks to see if theres any new products loaded to the website
instead of double-looping
.has will loop through all the data in array?
it's probably implementation-dependent
but i have no idea
but does it matter?
the loop won't be done in javascript, but in c++ or whatever, which is going to be a lot faster
Do I need to create a map of the array?
no, you can just do
new Set(<array comes here>)
E.g.: var pastProducts = new Set(["value1", "value2", "value3", "value4", "value1"]);
and this will also automatically get rid of duplicates
the annoying thing is to get the values back from it, which you have to do Array.from(set)
or [...set]
what if the value I'm checking for is from another array
what do you mean?
how do i iterate using
set.has(<value>)
you don't
or can <value> be an array ?
that's the point
no, you iterate over just
currentProducts
but if you make pastProducts
into a set, you don't need the 2nd forEach
Well
I'm going to be setting pastProducts = currentProducts after the check
because after every iteration, I want to check the new set
you can add the value to the set
and next time you check, the set will have the ids you had previously
This returns false
that's because you did the opposite
the idea is for
pastProducts
to be the new Set
hmm
I'm just a bit confused
So even if it's true
how would I do something afterwards ?
use an if statement to see if pastProduct has is true?
something like this
all that looping and checking is just a single
if
nowhmm
Logging as no match for me
you're looping the wrong thing
item is returning object
you're still looping the wrong thing
you have to loop data.products, you're looping [data.products]
currentProducts is equal to data.products
no, it isn't
you pushed an array into it
currentProducts.push(data.products)
thats an array with all the items under 1 index ([0])
so i have to loop through the [0] index?this is what you're doing
you're pushing an array into the array
so you have an array in the array
should i be iterating through the array originally so each entry is it's own index?
instead of setting my empty array to an array
you can do 2 ways: push the ones that don't exist, or concat 2 arrays
This works
yeah, because you aren't looping anything besides the products
those are different things
im hella confused now
lol
When I fetch the URL it returns JSON with 30 indexed items
I need to store each of these items into an array (currentProducts), which is why I looped through and added
this is how i would do it
but better formatted
forgot 1 line, added it now
pastProducts
will have all the idswon't this call regardless?
console.log("no match");
if you need to find by id, you can use a map instead of the array
no, because of the return
this is called a "guard clause" or "early return"
the return will skip pushing the product to array though, no?
yes
i need the products in array
so maybe ill get rid of the return for now
the return is essential
unless you want to add past products too
I need this data stored because this script will run continuously and check every X min
after the check, ill be setting pastProducts to currentProducts
so, if you are going to put all the data into the array, regardless of having seen it or not, why are you checking it?
This website for example : https://www.hanon-shop.com/collections/whats-new/products
HANON
What's New
Never miss a trick. Check out our newest styles and limited-edition sneakers, sourced from the secret corners of the streetwear world.
will randomly add new products to their website throughout the day
my goal is to be able to determine when a new product is added, by checking the JSON every X min and comparing to previous interval
that's quite different from what you're shown
Well, the pastProduct value was set to a fixed number just to test the logic
once i finish the logic for it, ill have to run it for a few hours to see if it actually works. It's just very basic rn but i have to add the setInterval, etc
thats why im confused with the .has because pastProducts will also be an array, so ill be comparing an array with an array. From my understanding, .has is only used for a fixed value
if you remove the
return
, you can set a variable to a value that lets you know that new products were added
but that will wait for tomorrow, because i should be sleeping 2 hours agohaha thank you for the input
Hit the hay
lol
by the way, everything there can be made into a map
and it would be way easier to do everything you need, except maybe looping, but that isnt too hard
Okay
Thank you
@ἔρως I managed to do this by creating a function with a for loop
🤮
but at long as it works...
Bad code?
Rn this returns all the array elements just to test the logic
where's the old products?
I pass products to oldProd
i will check this later
Let me know your thoughts, I’d like to improve wherever possible 👍🏻
Thanks
i have a few ideas
👀
so, what exactly do you want?
just so i can re-check your requirements and then go from there
I call that API and receive JSON
I then need to parse the JSON and store the ID (currentProducts). Then I check to see if products is not empty. If it’s not, I set currentProducts to products. Then check to see if currentProducts contains any id’s differing from the previous iteration. If there is a change, I then create a URL and output to signify there’s a new product loaded
TLDR: Scrape URL (consistently) and output when new products are loaded.
My current solution is a single iteration but I will be adding setInterval to consistently check @ἔρως
https://www.atmosusa.com/collections/new-arrivals/products.json returns the newest 30 products
you're describing what you want the code to look like
not what you want to do
Tldr
^
which features do you want the code to have?
just those?
We’ll I plan to add more
This was the starting point
then can you explain just the plan for the data processing, and part of the data rendering?
I’m confused
well, what do you intend to do with the data?
Why
Like how I plan to store it?
no, what do you plan to do with the data
im trying to understand the whole picture, not just the code
To log when new items arrive on page
Just practice code I’m trying to optimize
will to store the information somewhere?
Maybe in the future, idk
You mean like a DB?
no, stored localy in the browser (like a session storage or local storage or something else)
No won’t be doing that
This is just a practice solution I want to store it locally eventually, maybe on a text file using FS with Node, or a DB, to be able to practice
so, for now, just assume new data from the beginning?
Huh?
Just want to pull from API and check with previous iteration
i know that
im sure there's a much better way to do this, but will have to be for tomorrow
Ah okay
Lmk if you have any brief ideas which I can research
My code works but I’d like to do what’s Optimal
what's optimal sometimes isnt the best
im just trying to find a better solution than loops in loops or a function in a loop or something nasty like that
I found some different array methods to check for matches, but they just return a Boolean value
And I can’t seem to find any other solutions to compare two arrays besides loops
yeah, which is why i know there are better solutions
for example, i cant see why a map wont work for you
I’ll keep researching to see if I can find something
but i may be missing something
thats why i ask about intent, plans, prospects and all that, to be sure if something works or not
I tried to use .map with a for loop then compare but it wasn’t working
I don’t have the code atm on mobile
Makes sense
no no, not .map
a map
The logic may change depending on what I do with it
its like a set, but you use a key to map to a value
Map - JavaScript | MDN
The Map object holds key-value pairs and remembers the original insertion
order of the keys. Any value (both objects and
primitive values) may be used as
either a key or a value.
yes
I’m going to read about this now to try and figure it out. Maybe this’ll work, I originally tried the array method .map
that method is almost like a foreach, but takes the returned value and puts it in a new array
[1, 2, 3].map(x=>x*5)
returnd [5, 10, 15]
Ahh, makes sense. That’s why I wasn’t able to directly compare because it returns array
no, its because you cant compare arrays, since you are just checking if the object instance is the same or not
but the way i see this, is just a "shove everything into the map, save the ids of the recently obtained elements and render from there"
How would you iterate through the map then?
To determine similarities
For of?
why would you need to check for "similarities"?
what is a "similarity" anyway?
What solution would you recommend
I tried something like this
but can't seem to get .includes method to work
i wouldnt use .map since it is the wrong tool for the job
you can nail a screw with the handle of a screwdriver, but just because it worked doesnt mean that that's the right way to use those
what would you use ?
a single map
not .map, but a map
and how would you loop to find duplicates with two maps?
1 map
you can check if it has the id
but im not sure if it is the best solution
So similar to my example
Just with a map not map method
This
no, i would use a map and a set
or maybe 2 maps
actually, just 1 map and 1 set
the set would have the ids of the new items
and the map would have everything you need to render those
And how would you iterate between them to determine matches
I’m about to just redo this concept to determine based on updated time in the JSON instead of comparing IDs
you dont
that's the point of the map
you check if the map has the key, and if it doesnt, you add the object to the map and an id to the set
the set will have all the new ids to render
you loop through the set and get all the new ids
What’s the difference from using .has with map or .includes with array ?
speed
also, the set only takes unique values
and you can empty it super quickly
Okay good to know
with an array, to empty it, you have to do weird stuff like setting the lengh to 0
but the set has the .clear method
I’ll see if I can spin something up with that suggestion in about 30 min
You can’t just set array back to []?
you can, but that doesnt empty the array
that's a new array
new array means more memory allocations, and it may not free the old values for a bit, until the garbage collector runs
Is the old array stored somewhere?
not usually, no
Ahh okay didn’t know that
Also good to know, thanks
this is the minor concert to pick a set instead of an array
@ἔρως
I'm reading about Map now and am a bit confused about .get() method
Why does
console.log(map1.get('bar'));
return foo, seems like it should return bar? I don't quiet understand the mozilla explanation for thisbar is the key
foo is the value
its a key-value pair
ahh
Makes sense why there's undefined associated with each pair
store the objet as the value, and its done
So I need to set the key (as index) then value as id?
no, value as the entire object
all the IDs under one pair?
id => [all ids]
no
isnt it 1 big object per id?
each index returned is an object
yes, and you store all that stuff
Okay
and as the key, should I do something similar to array index?
Map(1, object)
Map(2, object)
etc?
Run a for loop, set the index to key and value to index.value (returned array)?
no, you use the .get method to obtain a value
To set value
yup
that's it
Ah this is much cleaner
I was looking to store the object data, I was going to in separate arrays
now you have everything
but the downside is that it doesn't tell you which ids are new
🥹
that is why you create a set
and then you check if the map has the id
if it doesnt, then add the id to the set
that's it
This is very frustrating lol
i think it is way easier than 2 loops
I need to do two loops still
A second loop to iterate and check for duplicates
Just can’t seem to get this damn has method to work lol
that's the magic trick
maps dont have duplicates
you cant map multiple values to a key
I need to compare it to the other map to see if there’s any changes
then do this: DONT
get the value from the map
Lol
And compare it to ?
you cant compare objects
I’m trying to compare the object ids
so, you need to find something else
why?
Man I’m trying to see if there’s any changes
the object id will always be the same
No
I’m trying to make the products
To see if there’s any new ids added
then do what i said
If the id is new then report it
I’m trying to but I have to loop through to check still
no, you dont
give me 90 minutes and i will make it work
My heads gonna explode
Ima step away for a few min getting frustrated with map😅
if it doesnt work its because you are doing something you shouldnt
but, i will help you after
What's the difference betwen Set & Map? Seems like they have similar methods and can set key to value (not same terminology, but something like
mySet1.add({ a: 1, b: 2 });
)
well, the name is self-explanatory to me
a set is a set of unique values
a map maps an unique key to a single value
is this the kind of logic you were thinking?
no, but its close
😅
This logic seems to work
but still contains two for loops
your loop works by miracle, if at all
lol
Why do you say this?
you created an empty map, then you are looping it
sets the key and value to the map though, no?
you are setting into products
but you loop newProducts
sorry, there was typo
your 2 loops should be 1
is there a method similar to .map i can use to set map values
besides looping
wait a bit
That looks good, studying it over
I appreciate it
you're welcome
@ἔρως
It works 👍
nice
by the way, i didn't test it at all
Most Shopify stores use similar url for their new products
I have a working solution already which I compared it to so I knew what site to test it on to see if it would pick up
I appreciate you helping with most my questions though. I’m still new to this but I’m learning a lot from these practical sample codes 👍🏻
that's how you learn
get your hands dirty
do something
Say for example if I wanted to run this across multiple websites
That would require node.js & multi threading?
nodejs? probably
multi threading? i dont think so
Wouldn’t I need to run the script (per site) separately?
fetch is asyncronous, so, probably not
All the products would be stored under the same variables and wouldn’t be differentiated between sites
are all shoppify ids unique between websites?
I believe so
so, if they are all unique (as in, the id is provided by shoppify itself, not by the instance), then you don't need to worry
Yeah but you’d need to be able to determine which new add came from where
Seems like a complicated mess
everything has an unique link
I’m thinking it would need to be multi thread
Because if this was scaled and delay times were lowered, Shopify would rate limit fast
If it was multi thread each could have its own IP which could prevent rare limiting from requests
Like for example if you were to run with 100 sites, it probably wouldn’t run at all considering the amount of request
that's not multi-threading
that's multiple processes
Yeah that’s what I mean
Where you can use this file as a function basically and call it per URL or something
I might not be using the right terminology
if you're worried about rate limits, yeah
If I wanted to add more data, such as variant sizing and availability, would it be bad to do a nested For Loop?
no, you need it