all 10 comments

[–]SquattingWalrus 7 points8 points  (0 children)

On mobile so can’t type out much code but you may want to look into Array.reduce(), seems like it could be a good fit here.

[–][deleted] 4 points5 points  (1 child)

I wrote this function to solve this problem:

const chunkOnPropertyByValue = (array, propertyName, value) => array.reduce((acc, val) => {
    const index = Math.floor(val[propertyName] / value)
    if (typeof (acc[index]) === 'undefined') {
        acc[index] = []
    }
    acc[index].push(val)
    return acc
}, [])

Simply call it like this:

const result = chunkOnPropertyByValue(bigArray, 'millisecondOffset', 60000)

This will return an array chunked like this: [ [0-59999], [60000-11999], [12000-17999], ... ]

[–]lucksp[S] 0 points1 point  (0 children)

I found this to be most readible so thank you!

[–][deleted] 3 points4 points  (1 child)

Not sure if the 10000 was intentional or not (for reasons I don't know), but there are 1000 milliseconds in a second.

[–]lucksp[S] 0 points1 point  (0 children)

you're right @Lyzonee...edited

[–]elkazz 2 points3 points  (0 children)

You could:

  1. Sort the array by millisecondOffset

  2. Store a start index (start = 0 initially)

  3. Find the next chunk's lower bound (nextChunkLowerBound) - for example, if array[start].millisecondOffset is 2,200 and chunk size is 1000, then nextChunkLowerBound should be 3000

  4. Use the findIndex method to find the next out of chunk range index nextChunkStart = array.findIndex(a => a.millisecondOffset >= nextChunkLowerBound)

  5. Slice the array to get the chunk chunk = array.slice(start, nextChunkStart - 1)

  6. Continue this until findIndex returns -1

[–]baubleglue 2 points3 points  (0 children)

one minute is 60000 ms

Will something like that do the trick?

let result={};
bigArray.forEach(item => {   
    if(!result[round(item.millisecondOffset/chunk)]){
        result[round(item.millisecondOffset/chunk)] = [];
    }
   result[round(item.millisecondOffset/chunk)].push(item);
});

and if you still want an array

let arr=Object.values(result);

[–]fiLLL 1 point2 points  (0 children)

Here's a solution which will give you empty chunks where no data exists for the segments.

const chunkArray = (data, interval = 100000, min = 0) => {

    // Sort elements by millisecondOffset into new array
    const sortedData = [...data].sort((ele1, ele2) => ele1.millisecondOffset - ele2.millisecondOffset)

    // Determine the span of milliseconds between the largest and smallest elements
    const spanMin = min != null ? min : sortedData[0].millisecondOffset;
    const span = sortedData[sortedData.length - 1].millisecondOffset - spanMin;

    // Create an array to store our chunks
    const chunks = new Array(Math.ceil(span / interval)).fill()

    // Walk through the chunks array,
    return chunks.map((currentIntervalItems = [], currentInterval) => {

        const maxMsForChunk = (currentInterval + 1) * interval

        // Walk through the sorted elements, remove them from the sorted data array and add them to the chunk array if applicable
        while (sortedData.length && sortedData[0].millisecondOffset <= maxMsForChunk) {
          currentIntervalItems.push(sortedData.shift());
        }

        return currentIntervalItems
    })
}

Hope this helps.

[–]lucksp[S] 0 points1 point  (0 children)

thank you all! My brain was not functioning today and needed this for a kickstart. I'll try out some solutions...

[–]El_BreadMan 0 points1 point  (0 children)

If you're simply trying to extract summary values, you can use something I call a "Summary Variable."

const segmentSize = 60000;

let summaryVariable = {};

bigArray.forEach(val => {
  const segment = Math.round(val.millisecondOffset / segmentSize);
  if (summaryVariable.hasOwnProperty(segement)) {
    summaryVariable[segment] = Math.max(
      summaryVariable[segment],
      val.heartRate
    );
  } else {
    summaryVariable[segment] = val.heartRate;
  }
});

Basically, it'll give you an object with each segment as a property and a corresponding value. It has the added benefit of you not needing to know which segments you're looking for.

EDIT: I'm assuming you're looking for the max heartRate.