0

When selecting check boxes, I create an array with its corresponding value / index using the below line.

days[dayCronValue] = dayString;

If I select Thursday, output is as follows.

days
> [ , , , , 'Thursday']

If I select Saturday, output is as follows.

days
> [ , , , , 'Thursday', , 'Saturday']

This works perfectly as what gets saved is not the string, but its index.

'0 0 0 * * 4,6'

The problem I have is that my method to remove the days when unchecked cannot replace the existing element with a 'missing' element. I use the map method to replace it with undefined. My thought process below.

days
> [ , , , , 'Thursday', , 'Saturday']

days[0]
> undefined

days = days.map(day => day === dayString ? undefined : day);

Eg. If I uncheck Thursday, output is as follows.

days
> [ , , , , undefined, , 'Saturday']

The cronString which gets saved is still the same, as undefined still represents an existing index.

'0 0 0 * * 4,6'

My logic thinks I should just do a forEach method to iterate over days for any typeof day !== 'undefined' and use the days[dayCronValue] = dayString to build a new array. This way, it creates a new array with the correct indexes and correct elements.

I just can't figure out how to do that (or if I'm just over-complicating this process).

Cheers!

Robert Hung
  • 145
  • 10
  • Just use for loop. – bhantol Dec 19 '16 at 23:19
  • Provide jsfiddle? – kind user Dec 19 '16 at 23:20
  • 1
    Is all you're trying to do to delete an element out of an array? Just use `delete days[4]` if you want to get rid of that element. – PMV Dec 19 '16 at 23:24
  • @PMV That wouldn't work, because when the loop is iterated over, with let's say `for(var i in days){console.log(i);}`, this is logged: `0, 1, 2, 3, 5, 6` – MasterBob Dec 19 '16 at 23:28
  • `delete days[4]` worked exactly. – Robert Hung Dec 19 '16 at 23:29
  • @MasterBob - Maybe I missed the intent, but I thought that is what he wanted to happen - he wanted a sparse array that only defined certain particular indices. – PMV Dec 19 '16 at 23:30
  • Your `toCronString` function simply should not test for the existence of the property, but for the value not being `undefined`. – Bergi Dec 19 '16 at 23:31
  • Possible duplicate of [How to remove a particular element from an array in JavaScript?](http://stackoverflow.com/questions/5767325/how-to-remove-a-particular-element-from-an-array-in-javascript) – Heretic Monkey Dec 19 '16 at 23:31
  • Yes, I didn't know it was called that but you're exactly spot on @PMV - if you want me to mark the question answered, can put it as an answer. – Robert Hung Dec 19 '16 at 23:31
  • @Bergi - I did try altering the filter in my humanToCron function to `days = days.map(day => days.indexOf(day)).filter(day => typeof day !== 'undefined').join(',');` but that didn't seem to work. – Robert Hung Dec 19 '16 at 23:36
  • 1
    @Rob I guess it would've worked if you had filtered the input, not the array of indices. – Bergi Dec 19 '16 at 23:39
  • @Bergi - It does seem a lot clearer now that I'm no longer frustrated, haha. – Robert Hung Dec 19 '16 at 23:41

2 Answers2

3

If the goal here is to create a sparse array (where only a few particular indices are defined), then the answer is just to use delete days[4] to delete the day at index 4.

PMV
  • 1,990
  • 1
  • 7
  • 15
0

You can use

var daystring = days.filter(day => day !== undefined).map((_, i) => i).join(',');

and don't need to care whether the properties don't exist of just don't contain a value. Notice that using delete on arrays, and using sparse arrays in general, is pretty bad for performance.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164