What is the best way to intersperse whole numbers among decimal elements within an array?

I have a function that takes an object with 5 arrays as input. One of the properties is named 'Indexes'. The purpose of this function is to fill in the array with zeros in ascending order, where all other arrays follow the Indexes array as their index. For example, if the Indexes array is [1,3], it will be filled with [1,2,3] and all other arrays will have 0 at position 2.

My current issue arises when the Indexes array contains decimals (a requirement for my work). For instance, if I have [43, 44.5, 45], I would like the result to be [43, 44, 44.5, 45]. However, the code I've written seems to skip whole numbers completely, making the process more complex than necessary.

Below is the function:


function fillMissingValues(csv) {
    // Function logic here
}

Here's an example of how to pass data to the function:

csv = {
        Indexes:[ 3, 4, 6.5, 8],
        'All reads': [1, 2, 3, 4],
        'Trimmed by Adapter or Quality': [1, 2, 3, 4],
        'Trimmed by adapter': [1, 2, 3, 4],
        'Trimmed by quality': [1, 2, 3, 4]
}

The expected output should look like this:

filledCSV = {
        Indexes:[0, 1, 2, 3, 4, 5, 6, 6.5, 7, 8],
        'All reads': [0, 0, 0, 1, 2, 0, 0, 3, 0, 4],
        'Trimmed by Adapter or Quality': [0, 0, 0, 1, 2, 0, 0, 3, 0, 4],
        'Trimmed by adapter': [0, 0, 0, 1, 2, 0, 0, 3, 0, 4],
        'Trimmed by quality': [0, 0, 0, 1, 2, 0, 0, 3, 0, 4]
}

Answer №1

Generate an array containing integers ranging from 0 to the highest value found in indexes.

Integrate the elements of the indexes array into this new array, eliminating any duplicates and arranging them in ascending order.

Iterate through this merged array. For each element that matches one in the indexes array, add the corresponding values from all other properties to the respective property in filledCSV. If no match is found, add 0 instead.

const csv = {
  Indexes: [3, 4, 6.5, 8],
  'All reads': [1, 2, 3, 4],
  'Trimmed by Adapter or Quality': [5, 4, 3, 2],
  'Trimmed by adapter': [5, 10, 15, 20],
  'Trimmed by quality': [10, 15, 18, 30],
}

const filledCSV = Object.fromEntries(Object.keys(csv).map(key => [key, []]));

let maxIndex = Math.max(...csv.Indexes);
let origIndexMap = Object.fromEntries(csv.Indexes.map((index, i) => [index, i]));
let filledIndexes = [...new Set([...Array(maxIndex).keys(), ...csv.Indexes])];
filledIndexes.sort((a, b) => a - b);
filledCSV.Indexes = filledIndexes;

filledIndexes.forEach(index => {
  let origIndex = origIndexMap[index];
  Object.entries(filledCSV).forEach(([key, array]) => {
    if (key != 'Indexes') {
      array.push(origIndex === undefined ? 0 : csv[key][origIndex]);
    }
  });
});

console.log(filledCSV);

Answer №2

  1. Iterate through the Indexes array with an incremented variable idx starting from 0. Populate a new array called filled while storing indices (found) of the existing values in filled.
  2. For the remaining arrays, create arrays filled with zeros and write the values in their respective indices.

const {Indexes} = csv, found = Array(Indexes.length), filled = [];

let idx = -1, i = 0;
while(i < Indexes.length){
  if(++idx < Indexes[i]) {
    filled.push(idx);
  }else{
    idx = Indexes[i]|0;
    found[i] = filled.length;
    filled.push(Indexes[i++]);
  }
}
 
const filledCSV = {Indexes:filled};
for(const k in csv){
  if(k === 'Indexes') continue;
  const arr = filledCSV[k] ??= Array(filled.length).fill(0);
  const from = csv[k];
  found.forEach((i, j) => arr[i] = from[j]);
}

console.log(JSON.stringify(filledCSV));
<script>
const csv = {
  Indexes: [3, 4, 6.5, 8],
  'All reads': [1, 2, 3, 4],
  'Trimmed by Adapter or Quality': [5, 4, 3, 2],
  'Trimmed by adapter': [5, 10, 15, 20],
  'Trimmed by quality': [10, 15, 18, 30],
}
</script>

` Chrome/122
------------------------------------------------
Alexander   1.00x | x1000000 264 269 273 277 278
Barmar     13.83x |  x100000 365 371 378 379 387
------------------------------------------------
https://github.com/silentmantra/benchmark `

const csv = {
  Indexes: [3, 4, 6.5, 8],
  'All reads': [1, 2, 3, 4],
  'Trimmed by Adapter or Quality': [5, 4, 3, 2],
  'Trimmed by adapter': [5, 10, 15, 20],
  'Trimmed by quality': [10, 15, 18, 30],
}

// @benchmark Barmar
{
const filledCSV = Object.fromEntries(Object.keys(csv).map(key => [key, []]));

let maxIndex = Math.max(...csv.Indexes);
let origIndexMap = Object.fromEntries(csv.Indexes.map((index, i) => [index, i]));
let filledIndexes = [...new Set([...Array(maxIndex).keys(), ...csv.Indexes])];
filledIndexes.sort((a, b) => a - b);
filledCSV.Indexes = filledIndexes;

filledIndexes.forEach(index => {
  let origIndex = origIndexMap[index];
  Object.entries(filledCSV).forEach(([key, array]) => {
    if (key != 'Indexes') {
      array.push(origIndex === undefined ? 0 : csv[key][origIndex]);
    }
  });
});
filledCSV;
}

// @benchmark Alexander
{
const {Indexes} = csv, found = Array(Indexes.length), filled = [];

let idx = -1, i = 0;
while(i < Indexes.length){
  if(++idx < Indexes[i]) {
    filled.push(idx);
  }else{
    idx = Indexes[i]|0;
    found[i] = filled.length;
    filled.push(Indexes[i++]);
  }
}
 
const filledCSV = {Indexes:filled};
for(const k in csv){
  if(k === 'Indexes') continue;
  const arr = filledCSV[k] ??= Array(filled.length).fill(0);
  const from = csv[k];
  found.forEach((i, j) => arr[i] = from[j]);
}
filledCSV;
}


/*@skip*/ fetch('https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js').then(r => r.text().then(eval));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Consider using React Components as an alternative to implementing pagination dots within Swiperjs, as it may help resolve the issue displaying

I seem to be encountering a small issue and I believe I am making a mistake somewhere. How can I replace the default dots with custom elements for pagination in Swiperjs for React? The custom element should return an SVG from an array of icons. Initially ...

What is the best way for me to grasp the concept and functionality of 'Array.prototype.join'?

When I tried using Array.prototype.join on a multidimensional array, I encountered a surprising result. To investigate further, I looked into the inner workings of Array.prototype.join and found it to be native code. [1,2,3,4,5,6,7,8].join('') [ ...

Could you show me how the easyrtcid is generated in the demonstration of audio-only chat? I would appreciate a step-by

Currently, I am utilizing the easyrtc webpage to test out the audio only chat demo and everything seems to be running smoothly. However, when connecting, the easyrtcid variable is automatically assigned a random string. I was wondering if there is a way t ...

Having trouble parsing the BODY of a NodeJs JSON post request?

I've been working on creating a basic API using nodeJS, but I've run into a problem while trying to post data. Below is my app.js file: const express = require('express'); const feedRoutes = require('./routes/feed'); const ...

Leveraging the power of NextJS and Strapi: Efficiently fetching multiple API pages with a single getStaticPaths

Both NextJs and Strapi offer guidance on fetching data from a single collection type within Strapi. The process involves the following code snippet: const pages = await (await fetch(getStrapiURL("/pages"))).json(); const paths = pages.map((page) => { ...

Improve your JavaScript form by implementing a time loading feature!

I am currently developing a sign-up form using native JavaScript and Ajax. The form utilizes an Ajax function to transmit data to a PHP engine, which then performs database queries. My main concern is implementing a loading function in JavaScript that can ...

Exploring the Origin of "props" in ReactJS

Currently, I am diving into the world of the official reactJS tutorial and you can find it here: https://reactjs.org/tutorial/tutorial.html#passing-data-through-props My journey with reactJS has been interesting so far, although there are still some parts ...

Using Nest JS to create two instances of a single provider

While running a test suite, I noticed that there are two instances of the same provider alive - one for the implementation and another for the real implementation. I reached this conclusion because when I tried to replace a method with jest.fn call in my ...

"Engage with an Angular directive using a button positioned in any location on the

There is a directive implemented on my webpage with an assigned id attribute, regardless of its functionality. Now, I need a second directive that essentially triggers the first one. Here is an example of what I aim to achieve: <body> <!-- v ...

What is the best way to display a variable from a function located outside of the public http folder in PHP?

I am attempting to create a registration form using Ajax. I have a script that calls a registration function located in an includes folder outside of the public html folder. The output of this function should be alerted, but when I click the button, the al ...

Creating dynamic images with PHP GD library

I am encountering a problem where Hindi text added to an image using PHP GD is appearing as squares. It seems like PHP GD does not support rendering Hindi text properly. Is there a solution to fix this issue? Alternatively, are there any other methods to ...

Accessing the Parent Variable from a Function in JavaScript: A Guide

How can you properly retrieve the value of x? let x = 5 const f = (n:number) => { let x = "Welcome"; return x * n // Referring to the first x, not the second one } Also, what is the accurate technical term for this action? ...

The auto-refresh feature of DataTables is not functioning as expected

Having trouble with the reload feature of DataTables. This is the code I'm using to load and reload the table on the server-side: $( document ).ready(function() { $('#dienst_tabelle').DataTable( { "ajax": "getData ...

Utilizing React componentDidUpdate for merging and appending data

I am working with a functional component that generates data in an object format from a state variable called scanlist: 0: brand: "AATEST" exp: "2022-08-25" gtin: "15735423000247" iname: "Arthur's Test Item" lot ...

Omit a Mongoose field in a query by utilizing the assignment operator

Despite recognizing that this question has been posed previously, I have not been able to find a solution suitable for my specific scenario. Many websites recommend using .select('-queryData'), but I am unsure how to implement it in my case. My ...

Counter cannot be accessed once it has been updated

When I click a button, an interval should start. The issue is that I'm unable to access the value of counter. The goal is for the interval to stop when the counter reaches 5. Here's an example: let interval = null; const stateReducer = (state, ...

Framer Motion's AnimatePresence feature fails to trigger animations when switching between pages

I'm running into issues with the Framer Motion library, specifically with the AnimatePresence transition. I've managed to make it work in normal situations, but when I encapsulate my Routes within a custom implementation, the exit animation fails ...

Check if a rotated rectangle lies within the circular boundary of the canvas

I have a rectangular shape that has been rotated using the ctx.rotate method, and there is also an arc on the canvas. My goal is to determine if any part of the rectangle lies within the boundaries of the arc. See the example below: https://i.sstatic.net/ ...

What are the steps to execute PhantomJS on a client machine?

I have implemented an HTML to PDF converter that utilizes phantomjs, following this method: npm install -g html-pdf var fs = require('fs'); var pdf = require('html-pdf'); var html = fs.readFileSync('./test/businesscard.html' ...

Exploring Typescript ENUMs

I need to save a list of alpha-numeric options as an ENUM in Typescript. Here is an example list: 1.134/2394 x 3-xyz 2.123/234 y 3-ery 3.345/99 t 4-red 4.4.1hv 3 secondary 5.2.51hv 3 secondary 6.1.61hv 3 secondary If anyone has thoughts on how to ...