hey everyone welcome back to our Channel I'm ysh Gupta in this video we are going to solve a frontend interview question from Uber's interview process this is a question often Ted in the machine coding rounds uh many people have reported to us and on the web that this question was asked uh currently you won't find this question anywhere on any other platform only on dep tools uh it's a fun question so let me explain what we are going to do here so initially you would have this uh box data basically shape data box data whatever you want to call it it would be a 2d array where each element could either be one or zero and using this data we have to create the shape basically uh empty boxes wherever the value is one and wherever the value is zero then we don't have to render anything or maybe whatever we are rending we should hide it so now let me go through the functional requirements let's say using the 2D array we have created the shape I can click on each empty box and once I click it then the color background color changes to Green that means it selected I cannot deselect it now and uh I can select all the empty boxes let's say I do that in this order now once I select the last box and then in the order of selection it should deselect let me show you again if I select these box in these order then in the order of selection they should deselect and once deselection process is happening then the click shouldn't happen this happened because the process was over let me just show you this quickly again so now this click is not getting registered so this is what we have to build in this uh interview question so without wasting any time let's get started so we have this data and uh right now the it is empty we are not seeing anything so let me create a component called shape. Js and we will in pass the shape here so let me just import this first so I'll say shape from so shape and I'll just create the component here or invoke it basically I'll say data and I'll pass the Box data here so right now this component is not returning anything so that's why we are getting an error so let's open this and let's close this so we have the shape component I'm just creating a skeleton for now just so that we don't see the error on the screen shape and we will just return it and this will get the data here which we are passing so basically this data is a 2d array now before starting any question or any problem uh it's always better to build a mental map or you know ask clarifying questions what we want to do if something you're not understanding always ask those questions don't directly jump into the code so from what I understand we need to create a shape basically an interactive shape based on the 2D data okay or 2D array um empty box uh where value equal to one and U When U value is equal to equal to zero then lender nothing or height whatever there is else or when we click on it uh we can select a box and change uh background color to so let's say green for now and deselect in the order of selection so that means order of insertion or selection matters so whatever data structure we want to use be it array or object or something we need to be mindful that uh the order of insertion matters so this is what we primarily want to do and uh when D selection process is happening then we have to uh disable any interaction okay so right now we have this 2D data which we saw earlier that it is an array of array uh basically something like this uh uh and we have to uh using this 2D array we have to render so first thing I want to do here is that I will uh make this 2D array into a 1D flat array so what I can do is boxes I can say data. flat infin and let me just you know I'll show you uh these U optimizations so I can say use memo import it from react and I'll memorize it right away I'll pass a call back here that uh it should be only called if data changes or okay so now let me make it a bit bigger okay so using this plat the 2D array we have converted into a 1D array which would be something like one one one uh 1 1 0 0 and 1 comma 1 comma 1 something like this so let's use this data to render our boxes so any I'll call this one uh give it a class name of boxes right now I'm just doing basic rendering so we'll break the question always break the question into you know itable uh and achievable part so right now I'm just doing rendering so we'll have boxes and I'll map over it and we'll have the box and the index here inside this I will just return a div I'll give it a key so I can use the a indexes here also because we are not doing any reshuffling or anything of that sort so we can use the air index uh so I'm going to use the Box value along with the index of the array as the key plus I'll give it a class name of let me import this package also so that we have go to file I'll use class names so I'll just import it we have the class names now let me just close this I'll uh import class name so that it will help help us uh handling the CSS better so this class class names package they will initially this box it's an empty so right now we'll just provide the box as a class so this is just rendering right now it's not showing anything because there is no styling here so let's open our style. CSS let me close this we will have boxes which would be the container let's say some sort of padding uh 50 pixel then each box we will say that each box width is 80 pixel and height is 80 pixel and we can say border of 1 pixel solid and we can say black so right now all these are all boxes but we have to convert it into a grid shape so for that we can use the CSS grid so uh display grid so this now we have to have three columns so what we are going to use is grid uh template columns here it's row we will just come columns so that means we have to Define three columns and each column should be flexible enough that it should have the width of its child that means the width of individual box so we have one f one fraction one fraction that means we are defining three uh columns now we will save withd uh fit content so that will just you know make it uh uh the each column will take the width of the boxes and we can have a gap of 20 pixels so now we have the grid here now we want that if uh we have the value as zero then we don't want to show that box right so what we can do here is inside this we can say what is the status if box is equal to equal to one then it should be visible else it should be hidden right and we can use this status as the class name and inside our CSS what we are going to do we can say that if box do visible then uh cursor is equal to pointer and we will take out the Border thing and we'll put it here and if the box is hidden then we can say opacity zero and cursor as initial now if you see we don't have anything here we'll just have the boxes and the our shape is created So based on uh how many what is the 2D array uh what values are you provided the shape will change but in this case this is the shape we want to work with so this works fine now we have created the basic structure we have uh mapped over our we did the flat version of the boxes we mapped over it we created the shape now it's time to add some sort of interactivity here that whenever we click on this box then the color should change so now let's see how can we do that so here we need a click Handler to handle this so we will say handle click it is going to take an event and we need so we need to know couple of things here we need to know uh what is the index of that box so that we can store it plus we need to know what is the status of that box is it visible nonvisible and of so s so we can add either add on click here so something like on click uh handle click here and this will attach the event handler to all the boxes but in an interview you or in any scenario when you are working with it we can just like we are you know optimizing flat using the flat here we can optimize here by uh taking it out and putting it on the parent that means what what we call is even Del event delegation that means if the this box is clicked the event is bubbled up to the parent and there is only one event handler so that will reduce our memory usage so this event handling event capturing and event bubbling these sort of uh concepts are also sometimes it's a follow-up question that if you add it to individual boxes they they'll ask you that if there is a large shape then it will have a large memory footprint so how can we decrease it and so on so now inside uh the our event handler we need the value so what we can do here is we can say we we need to uh have that index so we can pass the index plus we can pass the status here which is going to be either hidden or visible so inside our event handler what we are going to do is that we are going to take out the Target that means the element that was uh interacted with we can find the index with Target dot get attribute which would be index or in this case data index similarly we need the status so we can say status and this is the status so now since we have these data attributes we'll have we have these values but these values could be invalid let's say if we index is null or status is hidden let's say we we because we don't want to interact with hidden boxes right so if we have that we will just return it so that means these are guard rails or escap early Escape conditions that if I click on here on this empty space there is a box it is space I've just done opacity zero so the event handler will be there but I don't want to do any action when an empty SPAC is clicked that's why I'm uh handling these conditions here now we took care of the condition so we need some sort of data so our you know initially our requirement was that uh the order of insertion matters plus maybe when this box is clicked we need to know which box was clicked maybe we need to do some sort of quick access so the the options we have right now could be something like an array object map or set now since we need uh the order of insertion objects can handle uh you know keys in order they are inserted but it's not 100% reliable so we have option for array map and set but we need quick lookup also so that means we have option of map or set Now map is a key value pair we don't need values we just need the keys so set is the best option here so what we can do here is we can say selected and we can say set selected use State and we can pass a new set so this is throwing an error because we haven't imported use State here so we have the U State now so inside this what we are going to do is we can say set select and uh we'll have the previous value we are going to return a new set and we will add the previous value previous dot add and in this case the index so now this value is added but nothing is happening because we haven't done any action to reflect it in the UI so what we can do here is is that we can create a new variable called is selected if selected do has that means the current index the current box that we are rendering is part of the selected uh set then we are going to say we are going to add a class called selected and if we have that class so let's say if box do selected then we can add some background background color I think there is a color mentioned in the question yeah this one so we'll add this color here and we can say cursor uh not allowed So currently if we click on any box then it's uh not uh getting updated the background color is not changing or we don't know if the selected uh set is getting updated or not you can pause the video think about this that why this is not happening and mention your reasoning in the comments let's see why it's not happening so what what we are doing here is that we when we click on handle click then we are getting the uh index and status and we are pushing it into the set now the value that we are pushing into the set is a string but the array index here is a number so ideally what we are doing here is that if our set is 1 comma 3A 4 we are checking our selected which is the set only let's say it's one and has one so this is coming out to be false because we are checking a string against a number so to match this we can do two string and you see the the value was getting pushed that's why it started working so if I refresh now and if I select then all our boxes are getting selected so this uh completes the first part of our problem where we were rendering and added some basic uh interaction that now if we click on any boxes then our state is updating and we are reflecting that now comes the part that when the Box are completely selected then we have to deselect them one by one we can do that mult in a multiple ways one first is that uh in this set selected only in the event handler uh we will check that if our set is the size of a set is equal to the number of visible boxes then we can start uh uh deselecting here only or we can use an effect sometimes I like to use an effect so let's do that because this is in my mind it's an effect that when something happens do something else so so idea here is that when our selected do size is greater than equal to count of visible boxes or yeah visible boxes then we want to deselect but we don't have this value so let's compute this here we'll again use uh use memo and this will only be updated when our boxes change so from here boxer do reduce because we want to compute how many elements we have with the value one so we can say box here it will initially it will be zero so if our box is equal to equal to one then okay we will need the accumulator here accumulator + 1 and we'll return the accumulator and we'll use this value here so if selected do size greater than equal to this then we will do the unloading part or deselecting before we go to the unloading part we have to be mindful of one thing that uh as as of now this effect is getting executed on Mount because we haven't passed any uh dependency array but we want to call it whenever are selected changes so we'll update the dependency array here and then we'll go to the implementation of unloading so I'll create a method called unload so in this method what I want to do is that I want to remove uh boxes every 500 milliseconds so each box every 500 millisecond so for that we need the insertion order so we can say keys array prom and in this case uh from the selected do Keys we'll have all the keys here basically let's say our selection was in the order five then 3 then two and so on now we have this we'll create a method called remove next key so in this method if I have the keys that means keys. length that means we have any selected Keys then we'll do something else we do some uh some other processing we'll come to else part later so inside this what I want to do is that I want to find the current key which is going to be keys. shift so that means we'll get the five here now we want to remove the five from the selected set and update the state so what we want to do is set selected we'll have the previous value we'll clone it updated keys in this case we'll have new set from previous updated keys. delete current key and then we will return the updated keys and once we do that so basically we are getting five we are removing it from the set and we are updating the set we want to now move on to to the three value here and we want to do it every 500 millisecond so what we can do is we can call a timer set time out and we will pass uh remove next key on 500 milliseconds and to start with because initially we need to invoke this remove next key so we can call a timer here also set time out and we'll pass maybe 100 milliseconds so let's test it out if our logic okay we need to invoke this also so ins this we'll call it let's see if our logic is correct Let me refresh this so I'll select all the boxes and see as soon as we are done we are deselecting now uh this works fine but there might be some issues like if I click on this let's say if I select the final box then it should start deselecting but I can reselect the boxes again which is not the right way IDE delete our deselection is non- interruptable process that once it started we can should not be able to interact with any box so for that we can create a new state called uh unloading and in this case we can call set unloading initially it should be false and when we start unloading then we should set it to true and once we are done unloading that means we don't have any key then we should set it to false so this is the else part so now if I refresh this and if I run it see our Del loading oh sorry set unloading my bad my bad now if I refresh this and run it again then I'm not able oh we haven't added the check so here we'll say if unloading that if we have if unloading is happening because we added all the checks here that if index is null if status is hidden if we already have the selected value and now the final check that if unloading process is happening then we shouldn't do anything so we'll come back let me add this see now this nothing is happening no now the final unloading happened that that's why it's uh you know the state changed but let me show you again now nothing is happening so this take cares of of our original problem statement that we in rendered the boxes added interactivity and everything we can make it a bit more uh uh delightful that we can go to our styling and in this case for box we can say uh transition background color and 0.4 seconds is in and out so this will just uh make it a bit more delightful and the D loading would be a bit smooth also one followup question here could be that uh you know we are uh setting the timer or set timeout here and but we are not clearing it that shouldn't be a problem here because it's we are setting just one timer but just just in case to handle this what we can do here is that we can create a timer ref we can say use ref which is initially null and inside this whenever we are setting the timer we will get the timer ID here also and here also and if we don't have the keys then we will just clear the time out now if we just check we have rendered all the boxes we have rendered that if it's selected then the state should change and our final selection should show up and once we have selected then all our boxes are unselected if we try random order let's see if it's working fine see it's working exactly as expected so this brings end to our video I hope you were able to learn something new today it was an interesting question we talked about all the edge cases and uh even delegation effects and a lot of stuff if you feel that I have missed out on something or if I did something wrong then please do mention in the comments if you have a better solution then please do share in the comments or reach out to me on social media also there are two links on the screen top mate if you want to book a session with me uh practice any questions with me uh and if you just go want to go to the de tools Tech platform and start practicing then you can go to Dev tools. t/ practice and as always do like share and subscribe it means a lot uh your help towards raising the awareness would be would mean a lot so till next time see you take care bye-bye