Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

204
Visualizações
How can I interpolate zeroes sequences in a number array?

let's say I have an arbitrary number sequence

let sequence = [
  
    0, 0, 0, 0, 0,
    12, 64, 9, 6,
    0, 0, 0, 
    25, 79, 57, 13, 39,
    0, 0,
    7, 7,
    0, 0, 0, 0, 0,
    49,
    0
  
]; 

I need to replace all zeroes with interpolation given from non-zeroes neighbours, so the output would be

let output = [
  
    12, 12, 12, 12, 12,
    12, 64, 9, 6,
    10.75, 15.5, 20.25,
    25, 79, 57, 13, 39,
    28.3333, 17.6666,
    7,  7,
    14, 21, 28, 35, 42,
    49,
    49
  
];

While firs zeroes [0, 4] doesn't have left neighbour all their values have to be 12, while last zero has only right resident 49, it would be just 49.

For me, it doesn't really a problem to fill parts where both left and right neighbours are presented, however I'm looking for an universal and elegant solution for this task.

const interpolateValues = (array, index0, index1, left, right) => {
    
   let n = index1 - index0 + 1;
   let step = (right - left) / (n + 1);
   for(let i = 0; i < n; i++){
       
       array[index0 + i] = left + step * (i + 1);
       
   }
    
}

const findZerosSequences = (array) => {
    
    var counter = 0;
    var index = 0;
    var result = [];

    for (let i = 0; i < array.length; i++) {
        if (array[i] === 0) {
            index = i;
            counter++;
        } else {

            if (counter !== 0) {
                result.push([index - counter + 1, index]);
                counter = 0;
            }
            
        }
    }

    if (counter !== 0) { result.push([index - counter + 1, index]); }

    return result;
    
}
    
let sequence = [
  
    0, 0, 0, 0, 0,
    12, 64, 9, 6,
    0, 0, 0, 
    25, 79, 57, 13, 39,
    0, 0,
    7, 7,
    0, 0, 0, 0, 0,
    49,
    0
  
];
   
//[[0,4], [9, 11], [17, 18], [21, 25], [27, 27]]
let zeroes = findZerosSequences(sequence);
    
for(let i = 0; i < zeroes.length; i++){
    
    let lf = sequence[zeroes[i][0] - 1];
    let rf = sequence[zeroes[i][1] + 1];
        
    if(lf !== undefined && rf !== undefined && lf > 0 && rf > 0){
        
        interpolateValues(sequence, zeroes[i][0], zeroes[i][1], lf, rf);
        
    }
    
}

console.log(sequence);
        
let output = [
  
    12, 12, 12, 12, 12,
    12, 64, 9, 6,
    10.75, 15.5, 20.25,
    25, 79, 57, 13, 39,
    28.3333, 17.6666,
    7,  7,
    14, 21, 28, 35, 42,
    49,
    49
  
];

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

If anyone would be interested in spaghetti instead of a valid answer :)

const sequence = [
    0, 0, 0, 0, 0,
    12, 64, 9, 6,
    0, 0, 0, 
    25, 79, 57, 13, 39,
    0, 0,
    7, 7,
    0, 0, 0, 0, 0,
    49,
    0
]

const output = sequence.join(',')
.replace(/^([0,]+)(\d+)/, (_, zeros, number) => {
  const n = zeros.match(/0/g).length
  return (number + ',').repeat(n) + number
})
.replace(/([^0,]+),([0,]+)([^0,]+)/g, (_, number1, zeros, number2) => {
  const n = zeros.match(/0/g).length
  const diff = +number2 - +number1
  const step = diff / (n + 1)
  return number1 + ',' + [...Array(n).keys()].map(i => {
    const val = +number1 + (i + 1) * step
    return Math.floor(val * 10000) / 10000
  }) + ',' + number2
})
.replace(/(\d+)([,0]+)$/, (_, number, zeros) => {
  const n = zeros.match(/0/g).length
  return number + (',' + number).repeat(n)
}).split(',').map(Number);

console.log(output)

about 4 years ago · Juan Pablo Isaza Relatório

0

You almost got it, let the interpolateValues worry about those edge cases which are easily resolved.

let sequence = [
  0, 0, 0, 0, 0,
  12, 64, 9, 6,
  0, 0, 0,
  25, 79, 57, 13, 39,
  0, 0,
  7, 7,
  0, 0, 0, 0, 0,
  49,
  0
];

const interpolateValues = (array, index0, index1, left, right) => {

  if (left === null) left = right;
  if (right === null) right = left;
  if (left === null && right === null) left = right = 0;

  let n = index1 - index0 + 1;
  let step = (right - left) / (n + 1);
  for (let i = 0; i < n; i++) {
    array[index0 + i] = left + step * (i + 1);
  }

}

const findZerosSequences = (array) => {

  var counter = 0;
  var index = 0;
  var result = [];

  for (let i = 0; i < array.length; i++) {
    if (array[i] === 0) {
      index = i;
      counter++;
    } else {
      if (counter !== 0) {
        result.push([index - counter + 1, index]);
        counter = 0;
      }
    }
  }

  if (counter !== 0) {
    result.push([index - counter + 1, index]);
  }

  return result;
}

let zeroes = findZerosSequences(sequence);

for (let i = 0; i < zeroes.length; i++) {
  let lf = zeroes[i][0] - 1 >= 0 ? sequence[zeroes[i][0] - 1] : null;
  let rf = zeroes[i][1] + 1 < sequence.length ? sequence[zeroes[i][1] + 1] : null;
  interpolateValues(sequence, zeroes[i][0], zeroes[i][1], lf, rf);
}

console.log(sequence);

about 4 years ago · Juan Pablo Isaza Relatório

0

Here's a solution that accepts your input array and returns the interpolated output array. I put comments inline with the code to explain how it works. This solution also behaves correctly for arrays of all zeros.

function interpolateArray(input) {
    let output = []; // New array for output
    let zeros = 0; // Count of sequential zeros
    let start = 0; // Starting number for interpolation
    for (let i = 0; i < input.length; i++) { // Loop through all input values
        let value = input[i]; // Current input value
        if (value === 0) zeros++; // If value is zero, increment the zero count
        else { // If the value is non-zero...
            if (start === 0) start = value; // If the starting value is zero, set start to current non-zero value
            if (zeros) { // If there are zeros accumulated...
                let step = (value - start) / (zeros + 1); // Compute the step value (current value, minus start, divided by total steps)
                for (let j = 1; j <= zeros; j++) output.push(start + (j * step)); // For each zero, push the stepped value to output
                zeros = 0; // Reset zero count
            }
            start = value; // Store the current value as the new start
            output.push(start); // Push the current non-zero value to output
        }
    }
    for (let j = 0; j < zeros; j++) output.push(start); // If there are accumulated zeros, that means they were trailing. Push last non-zero value to output for each
    return output; // Return the output
}

Update:

Just for fun, I tightened up the code a bit so the function is more compact. It works exactly the same.

function interpolateArray(input) {
    let output = [], zeros = 0, start = 0;
    input.forEach(value => {
        if (value) {
            start = start || value;
            if (zeros) {
                let step = (value - start) / (zeros + 1);
                while (zeros--) output.push(start += step);
                zeros = 0;
            }
            output.push(start = value);
        } else zeros++;
    });
    while (zeros--) output.push(start);
    return output;
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda