Discover pairs of values that correspond to various ratios within an array

Working with Google Apps Script:

I have a scenario where I need to process two arrays. The first array contains monetary values extracted from an invoice, and the second array contains applicable VAT/tax rates.

The goal is to pair each tax value with its corresponding monetary value from the array.

To illustrate, consider the following input:

https://i.sstatic.net/trAqsdBy.jpg

Based on the given input arrays:

values = [4000, 2500, 2066.12, 2000, 1834.86];
        taxRates = [9,21];
    

The expected output in this case would be:

taxAmounts = [[2000, 2500], [1834.86, 2066.12]];
    

This resulting output corresponds to the colors shown in the provided image, indicating the source of each number:

taxAmounts[0][0] = 2000    = green  = inclusive tax amount (for taxRates[0])
    taxAmounts[1][0] = 1834.86 = brown  = exclusive tax amount (for taxRates[0])
    taxAmounts[0][1] = 2500    = yellow = inclusive tax amount (for taxRates[1])
    taxAmounts[1][1] = 2066.12 = pink   = exclusive tax amount (for taxRates[1])
    

In essence, the objective is to compute:

inclusive tax amounts for each tax rate specified in 'taxRates'
    exclusive tax amounts for each tax rate specified in 'taxRates'
    

Approach Taken:(pseudo code)

Algorithmically search for two items in the array that differ by 21%
     Upon finding, check if the higher of these numbers is also the maximum within the array
         If it's the highest number --> return this number (indicating only one tax bracket)
         If not the highest number --> multiple tax brackets exist
             Check for matching value pairs for the next item in the 'taxRates' Array (recursive approach)
                 If sum of the found numbers equals the highest number in the array --> 
                    Return these two numbers
                 Else continue searching for lower percentage values, e.g., 104%, until...
                    ...sum of all matched values equals the highest number in the array, then return these numbers
                       If no suitable match is found after exhaustive checks
                           Return undefined;
    

Attempts have been made to implement the above logic into code form, but so far the output isn't as anticipated. There likely exists room for improvement in writing a more efficient solution.

Snippet of the attempted code:

function findBtwPairs(btwRates, amountsArr, incBtwArr, exBtwArr){
      // Code implementation here...
    }
    // Helper functions defined below...

    function sumArray(array){
        return array.reduce(add, 0);
    }

    function add(accumulator, a) {
        return accumulator + a;
    }

    function roundTo(num, decimals) {
        return (+num.toFixed(decimals));
    }
    

Answer №1

I believe this solution will be beneficial

function identifyTaxPairs(tax, amounts) {
    let taxValues = [];

    for (let singleTax of tax) {
        let located = false;

        for (let x = 0; x < amounts.length; x++) {
            for (let y = x + 1; y < amounts.length; y++) {
                let exclusiveTax = amounts[y];
                let inclusiveTax = amounts[x] - exclusiveTax;

                if (Math.abs(inclusiveTax / exclusiveTax * 100 - singleTax) < 0.01) {
                    taxValues.push([amounts[x], exclusiveTax]);
                    located = true;
                    break;
                }
            }
            if (located) break;
        }
    }
    return taxValues;
}

// An illustration of how to use the function:
let amounts = [4000, 2500, 2066.12, 2000, 1834.86];
let taxRates = [9, 21];
let output = identifyTaxPairs(taxRates, amounts);
console.log(output);

Answer №2

After some extensive revisions, I have improved the structure of my code;

Here is my updated code:

        var valuePairs = [];
var inc; var ex;
var amounts = [ 5000, 2000, 2000, 1834.86, 1652.89, 1000, 961.5385, 15, 12,3,1];
var btwTypes = [21,13,9,4];

function tester(){
  // console.log(roundTo(5000,0));
  console.log("final output = [" + theBtwFinder(btwTypes) + "]");
}

function theBtwFinder(rates){
  while(rates.length>0){
    if (findValuePair(rates[0]) != undefined){
      valuePairs.push(findValuePair(rates[0])[0]); valuePairs.push(findValuePair(rates[0])[1])

      if(roundTo(sumArrayEvenIndices(valuePairs),0) == roundTo(amounts[0],0)){
      return valuePairs;
      }
      }
      btwTypes.shift(); //remove first item of 'btwTypes' Array since we're done checking for that btw percentage
    }
  }

function findValuePair(deltaPercentage){
  for(i=0;i<amounts.length;i++){
    for(j=0;j<amounts.length;j++){
      if(i!=j){ //don't check value against itself
        if ( roundTo(amounts[i]/amounts[j], 2) == (1 + deltaPercentage/100) ){
          inc = amounts[i]; ex = amounts[j];
          return[inc, ex];
        }else if( roundTo(amounts[i]/amounts[j], 2) == (deltaPercentage/100) ){
          inc = amounts[i]+amounts[j]; ex = amounts[j];
          return[inc, ex];
        }
      }
    }
  }
  return undefined; //no pair found
}

// $$$ HELPER FUNCTIONS $$$
function sumArrayEvenIndices(array){
  var sum = 0;
  for(index in array){
    if (!(index % 2)){ //of index is even
      sum += array[index];
    }
  }
    return sum; 
    }

function roundTo(num, decimals) {
  return ( +num.toFixed(decimals));
}

A visual illustration of the code's function:

User input: https://i.sstatic.net/TM5UlfZJ.png

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

Attempting to iterate through the div in order to collect all of the checkboxes and assign a label to each one

I am attempting to modify a piece of JavaScript code in order to locate all checkboxes, assign names to them, and then add label attributes with CSS for accessibility purposes. Here is the snippet of my existing code: <tr class="el-table__row" ...

Navigate forward to the next available input in a grid by using the tab key

My goal is to improve form entry efficiency by using the tab key to focus on the next empty input field within a grid component. If an input field already has a value, it will be skipped. For example, if the cursor is in input field 2 and field 3 is filled ...

Clean URL with CodeIgniter arrays in the GET variable

Is there a way to change an URL with an Array in GET to a CLEAN format? For example: Instead of: example.com/school/4/?city[]=1&city[]=2&city[]=3 I want: example.com/school/4/?city=1,2,3 (Using the Codeigniter framework.) I've considered ...

Is it possible to notify the user directly from the route or middleware?

In my current setup, I am utilizing a route to verify the validity of a token. If the token is invalid, I redirect the user to the login page. I am considering two options for notifying users when they are being logged out: either through an alert message ...

Utilizing ReactJS and Plyr in tandem for Vimeo API Integration

I'm encountering an issue with my React component that utilizes the https://github.com/selz/plyr media player. Everything works as expected until I unmount the component, triggering an error from the Vimeo API. The specific error is: Uncaught (in prom ...

Having trouble confirming signature with Node.js Crypto library, specifically with key pairs

I have a concise nodejs code snippet where I attempt to sign a string and then verify it using node crypto along with key pairs generated through openssl. Despite trying various methods, the result consistently shows "false" indicating that the signature c ...

Leveraging the csv file functionality in the npm package of d3 version 5

Currently in my react project, I am utilizing d3 for data visualization. After installing the d3 module via npm, I found myself with version 5.9.2 of d3. The challenge arose when attempting to use a csv file within d3. Despite scouring various resources, I ...

Angular view not reflecting changes made to the model

Here is a straightforward Angular application I created to play audio using the JavaScript web Audio Object: app.component.ts export class AppComponent { title = 'media player'; audio; currentTime: number; constructor() { this.audi ...

Exploring the nuances of receiving responses with NextJs, Nodemailer, and Fetch

Currently in the process of constructing a basic contact form with Next.js, nodemailer, and fetch. Despite successfully sending emails from the frontend form to the designated email account, the network shows the contact submission as pending. After approx ...

"Encountering an issue with Next.js where the Redux

Hey there, I'm working on a simple project using Nextjs. I need to access the state of my Redux store but I'm encountering an error when trying to use store.getState, it's throwing an error saying getState is undefined. Additionally, I have ...

Implement a shaking animation for a div when the input fields are not valid

Does anyone know how to make these divs shake when the inputs are not valid (or empty)? Here is a link to what I have tried so far: http://jsfiddle.net/jalxob/ahQLC/13/ I attempted to accomplish this by using: .effect('shake'); If anyone h ...

A multimedia player featuring various video source files and multiple text track options

My issue involves a video element where the user can choose from a list of options to play. Each video has an associated text track, but I am having trouble setting the new text track when a different video is selected. In my html, I have: <video id ...

Utilizing jquery and ajax to showcase a series of images prior to uploading them

I have been attempting to create a feature that allows for the preview of multiple images before uploading them to my website. Unfortunately, it's not working as expected and I am unable to identify any errors in the console. Below is the JavaScript c ...

Steps to fix the Error: connect EISCONN ::1:5555 - Local (:ffff.127.0.0.1:5555)

Currently, I am in the process of developing an Electron app where I need to establish a connection with a TCP port on my local machine. However, upon starting the application, I encounter the following error message: "A JavaScript error occurred in the ma ...

Controlling the window opener; Inserting text into an element in the parent window

A pop-up window allows users to select files, then displays the selected image's URL. However, I need to take additional steps beyond that. I am seeking a method to input the URL into an input element on the parent window. window.opener.document.wri ...

Incorporate a dynamic PowerPoint presentation directly onto my website

In my situation, on the client side, users can select image files (jpg|png|gif), PDF files, and PPT files which are then stored in a database. When viewing these selected files in the admin panel, I am using conditional statements to display them appropr ...

Exploring the Modularity of Post Requests with Node.js, Express 4.0, and Mongoose

Currently, I am immersed in a project that involves utilizing the mean stack. As part of the setup process for the client-side, I am rigorously testing my routes using Postman. My objective is to execute a post request to retrieve a specific user and anot ...

How to use jQuery to dynamically assign a class to an li element

I'm attempting to use jQuery to add the 'block' class to specific li elements, but for some reason the class isn't being applied. The goal of the program is to display time slots and disable certain ones if they are blocked. Here's ...

The Material-UI DataGrid feature allows for the display of column sums, with the sum dynamically updating based on applied filters

I am struggling with calculating the sum of values in the Total Amount column of my Material-UI DataGrid. How can I achieve this and ensure that the sum is also updated when a filter is triggered? Any guidance on how to sum the entire Total Amount column ...

Return all HTML code from the Ajax element

I can't seem to pinpoint the issue with my code. When I make an ajax call using the code below: ajax.js: function ajaxObj(meth, url){ var x = new XMLHttpRequest(); x.open(meth, url, true); x.setRequestHeader("Content-type", "application/x-www_form-u ...