Home > OS >  Javascript calculate intervals from range using min/max and map to n size array indexes
Javascript calculate intervals from range using min/max and map to n size array indexes

Time:10-05

You are given timestamps(list), scale_min(number), scale_max(number), interval(string) and curr_interval(string).

Timestamps are in order from oldest: 0 to newest: timestamps.length - 1 and can be added upon infinity.

Using the scale's min, max and interval, generate a list.

Example 1

Input: timestamps=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], scale_min=.5, scale_max=1.5, interval='.1', curr_interval='1.5'
Output: 10
Explanation: The generated list of scales = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']
with the current interval being '1.5', the index of that interval on the timestamps is 10

Example 2

Input: timestamps=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], scale_min=.5, scale_max=1.5, interval='.1', curr_interval='1.5'
Output: 12
Explanation: The generated list of scales = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']
with the current interval being '1.5', the index of that interval on the timestamps is 12

Example 3

Input: timestamps=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], scale_min=.5, scale_max=1.5, interval='.1', curr_interval='1'
Output: 5
Explanation: The generated list of scales = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']
with the current interval being '1' the middle, the middle index on timestamps is 'f'(5)

Example 4

Input: timestamps=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], scale_min=.5, scale_max=1.5, interval='.1', curr_interval='1'
Output: 6

Constraints

timestamps.length > 0

scale_min < curr_interval < scale_max

As far as I've gotten

var values = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'];
const minimumScaleValue = .5;
const maximumScaleValue = 1.5;
const scaleInterval = .1;
let currentScale;

var scaleRange = [];

for (let i = minimumScaleValue; i < maximumScaleValue; i  = scaleInterval) {
    scaleRange.push(i.toFixed(2));
}
scaleRange.push(maximumScaleValue.toFixed(2));

currentScale = 1.2;
const solution1 = values[scaleRange.indexOf(currentScale.toFixed(2))]
// scaleRange = ['0.50', '0.60', '0.70', '0.80', '0.90', '1.00', '1.10', '1.20', '1.30', '1.40', '1.50']
// index = scaleRange.indexOf(currentScale.toFixed(2)) = 7
// values[7] = h, correct
console.log(scaleRange, solution1)

currentScale = 1.5;
const solution2 = values[scaleRange.indexOf(currentScale.toFixed(2))]
// scaleRange = ['0.50', '0.60', '0.70', '0.80', '0.90', '1.00', '1.10', '1.20', '1.30', '1.40', '1.50']
// index = scaleRange.indexOf(currentScale.toFixed(2)) = 10
// values[10] = k, correct
console.log(scaleRange, solution2)

// adding more data
values.push('l');

currentScale = 1.5;
const solution3 = values[scaleRange.indexOf(currentScale.toFixed(2))]
// scaleRange = ['0.50', '0.60', '0.70', '0.80', '0.90', '1.00', '1.10', '1.20', '1.30', '1.40', '1.50']
// index = scaleRange.indexOf(currentScale.toFixed(2)) = 10
// values[10] = k, incorrect, should be l
console.log(scaleRange, solution3)

CodePudding user response:

It seems relatively straightforward to get the index or the actual array value, with code like this:

const getIndex = (xs, min, max) => (x) =>
  Math.round((xs .length - 1) * (x - min) / (max - min))

const getValue = (xs, min, max) => (x) =>
  xs [Math.round((xs .length - 1) * (x - min) / (max - min))]

const tests = [
  {timestamps: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], 
   scale_min: .5, scale_max: 1.5, curr_interval: 1.5},
  {timestamps: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], 
   scale_min: .5, scale_max: 1.5, curr_interval: 1.5},
  {timestamps: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'], 
   scale_min: .5, scale_max: 1.5, curr_interval: 1},
  {timestamps: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], 
   scale_min: .5, scale_max: 1.5, curr_interval: 1},
]

tests .forEach (({timestamps, scale_min, scale_max, curr_interval}) =>
  console .log (`${timestamps .join ('')} - [${scale_min} - ${scale_max}] - ${curr_interval} --> '${
    getValue(timestamps, scale_min, scale_max) (curr_interval)              
  }' (index ${getIndex(timestamps, scale_min, scale_max) (curr_interval)})`)               
)

But I'm concerned that this might be missing something as you supply curr_interval as a string and include the entirely derivable interval (which I ignore.) What is this solution missing?

This does depend on min being less than max and on curr_interval falling in that range. But if either fails, it should simply return undefined, which seems reasonable.

  • Related