Removing elements from an array

I have an array which which every click event 3 elements are added to it.
So it starts having 3 elements and-for example-on third click it has 9.

What I am trying to achieve is that after the first click the elements are removed so it must always have 3…I have checked some array methods(slice,splice etc…)but I really do not know what to use.

Could you give an example of the desired behaviour, since I can’t imagine it from the description given.

If it were to remove only the first array element, shift() could work

I suppose you could do that 3 times, but that’s a bit hacky. IMHO, it would be better to use splice()

Maybe what’s tripping you up is that arrays start with the index 0 not 1 ?

Wouldn’t it be easier to simply assign a new array then? ^^ If you want to implement something that behaves similar to a circular queue though, a possible solution might go like

const pushCyclic = (array, ...values) => 
  array.concat(values).slice(-array.length)

const myArray = [1, 2, 3]

pushCyclic(myArray, 4)          // -> [2, 3, 4]
pushCyclic(myArray, 4, 5)       // -> [3, 4, 5]
pushCyclic(myArray, 4, 5, 6)    // -> [4, 5, 6]
pushCyclic(myArray, 4, 5, 6, 7) // -> [5, 6, 7]

how this could be done…by creating a new array.
Can you give an example?

As @Dormilich says it’s a bit difficult to answer without seeing your code, but from what I gather it might look like

let myArray = ['three', 'initial', 'elements']

myButton.addEventListener('click', () => {
  myArray = ['some', 'new', 'elements']
})

When it comes to the array, do you want each new item going in the array to push out an old item, maintaining a total number of 3 items in the array? If so, that is called a FILO system (First In, Last Out).

Good question. I had assumed the code was meant to work with three values at a time.

But if it is one value at a time and the array length is to be kept at three, then should it be unshift/pop or push/shift ?

@designtrooper as you can see, there are many different ways to work with arrays. Can you clarify the requirements?

Ok…I am going to describe precisely the problem(I avoided doing so from the beginning cause it might be lengthy)…anyway:

Take a look at this fiddle…click the black diagonal line as indicated by the message(shown)…part of the content changes below,click again for the second time and open the console to see the error produced(regarding indices).
The error produced is due to the fact that content in line 9 is no more and as such the array is empty…I got the idea from somewhere that indices should be global so that the array has always data in it-and no error is produced that way.

And here comes the reason why I made this post originally:
If the array is global any subsequent click adds more elements(undefined,since the HTML has been altered) to it while keeping the original values.
So the aim here is to keep the initial values and strip off the array it’s undefined ones which increase in number every time the user clicks.

P.S If I was lengthy sorry…I had to in order for you to understand better the problem.

very quick reply (without checking the fiddle):

if the fix simply is to remove undefined array entries and you don’t care for the indices, run your array through a filter to remove the undefined elements.

arr = arr.filter( e => e !== undefined )

looking the fiddle is good…for another reason too.
I have another problem also,where to place the filter function so as to achieve the desired outcome…

The better option is to fix the indices array creation. Currently you create as many entries as you have services, which is too hard a dependency. better create the array from the data of interest, but for that you need a common class name (like show_price) then you fetch only the data you want.

But we can get off even without using arrays at all! What you originally want is to replace certain elements. This is not that complicated to do with only jQuery.

$('.show_price')
  // fetch only those sections that have a sub-element with the .value class
  .filter( (i, e) => $('.value', e).length === 1 )
  // replace content in remaining elements
  .replaceWith( function () {
    var value = $('.value', this).data('value')
    return '...' // HTML to replace the original content with
  } )

Note: This is a demonstration of the holy trinity of functional programming functions: map - filter - reduce (the DOM elements are the list, filter is there, and replaceWith is essentially a specialised version of map)

PS. to get the necessary indices for the form element names, I’d use the count of <fieldset> elements that you wrap around each inserted section (this is why semantics are important, it makes life much easier in the long run).

1 Like

before examining the non-array solution let’s get some things straight…
I do create the array from data…just take a look at line 9 of the fiddle where I get the value of the data attribute(in this case one)…did you noticed that?

what I meant is that you create the entries, no matter if the selector matches an element or not (that’s why $('.show_price0 .value').data() returns undefined the second time).

Would you want to move that array creation and first for loop, outside of the click event?

No, as there could be more services. As outlined, I’d avoid the use of a helper array to begin with.

1 Like

yes it seems I can do my job without array…I want to do some testing before concluding that this is the solution…thanks.

But it seems we are in the right track…

there is a problem though…take a look at the fiddle.
Two services are listed along with the price visibility option.If you click the edit button the price visibility option changes to display the radio buttons with yes/no checked…both services ought to have one radio button checked,yes or no.
Here you see that this applies only to the second service…
When using the array I did not have this problem…but with this new code this just appeared…
I hope you understand what I am trying to say…

I think that an understanding of the problem might be beneficial here.

The first time the click event occurs, the code does create an array from the data. Then when using replaceWith, the data is destroyed due to the elements containing the data being replaced with other different elements instead.
When the function ends, that array of information that was created, is lost too.

The next time the click event occurs, the data no longer exist. The array is created again, but has no data to retrieve.

if you noticed we are in a different stage now…I am in the stage of implementing the solution at post 12.