JavaScript code that filters and combines two arrays based on the matching of two fields or columns

Looking for a solution with childcare schools - I have two sets of data that I need to match based on specific columns:

Attendance by Department: [date, department, attended]

    0: (3) ["09-30-2019", "00_Infants", 22]
    1: (3) ["09-30-2019", "01_Ones", 38]
    2: (3) ["09-30-2019", "02_Twos", 40]
    3: (3) ["09-30-2019", "03_Threes", 42]
    4: (3) ["09-30-2019", "04_Fours", 19]
    5: (3) ["10-01-2019", "00_Infants", 27]
    6: (3) ["10-01-2019", "01_Ones", 42]
    7: (3) ["10-01-2019", "02_Twos", 51]

ETC...

Expenses by Department [date, department, expense]

    0: (3) ["09-30-2019", "00_Infants", "584.56"]
    1: (3) ["09-30-2019", "01_Ones", "701.51"]
    2: (3) ["09-30-2019", "02_Twos", "614.02"]
    3: (3) ["09-30-2019", "03_Threes", "442.50"]
    4: (3) ["09-30-2019", "04_Fours", "166.65"]
    5: (3) ["09-30-2019", "06_Floater", "141.37"]
    6: (3) ["09-30-2019", "07_Office", "246.91"]
    7: (3) ["09-30-2019", "08_Administration", "0.00"]
    8: (3) ["09-30-2019", "09_Director", "0.00"]
    9: (3) ["09-30-2019", "12_Kitchen", "0.00"]
    10: (3) ["10-01-2019", "00_Infants", "760.37"]
    11: (3) ["10-01-2019", "01_Ones", "756.48"]
    12: (3) ["10-01-2019", "02_Twos", "640.23"]
    13: (3) ["10-01-2019", "03_Threes", "552.66"]

--

The goal is to link Expense.date && Expense.department to Attendance.date && Attendance.department ONLY if the .department appears in Attendance[] THEN, add Expense.expense to the corresponding record in Attendance

I've experimented with mapping, filtering, d3.js nest(), Object.assign(), ifs, $.each...

Here's the messy code snippet where I attempted different solutions even though they didn't really work as expected.

    let ffs = attended.map(function (x, i) {
    return {
        "date": emp[x],
        "other": emp[i][0]
    }
    }.bind(this));

let mfer = attended.map(x => Object.assign(x, emp.find(y => y[0] === x[0]));

Expected outcome: [date, department, attended, expense]

    0: (3) ["09-30-2019", "00_Infants", 22, 584.56]
    1: (3) ["09-30-2019", "01_Ones", 38, 701.51]
    2: (3) ["09-30-2019", "02_Twos", 40, 613.02]

Actual results: pretty much everything but that.

My browser history shows 115 searches related to this issue from yesterday at 7 PM until today at 8:30 AM.

I feel like there should be a simple solution to this, but being in a learning phase, it's more challenging than I anticipated.

- I think I'm getting closer to what I need, although things get blurry when trying to apply the second filter to target departments:

Applying filter within a filter in JavaScript

some tabs stay open...

Find all matching elements within an array of objects

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

Javascript multiple filters array

merge two arrays including some fields from each

Answer №1

Loop through the Attendance array and use Array.prototype.find() to search for a matching entry in the Departments array. If a match is found, the parsed amount is added to the attendance entry.

const attendance = [["09-30-2019", "00_Infants", 22],["09-30-2019", "01_Ones", 38],["09-30-2019", "02_Twos", 40],["09-30-2019", "03_Threes", 42],["09-30-2019", "04_Fours", 19],["10-01-2019", "00_Infants", 27],["10-01-2019", "01_Ones", 42],["10-01-2019", "02_Twos", 51]];
const departments = [["09-30-2019", "00_Infants", "584.56"],["09-30-2019", "01_Ones", "701.51"],["09-30-2019", "02_Twos", "614.02"],["09-30-2019", "03_Threes", "442.50"],["09-30-2019", "04_Fours", "166.65"],["09-30-2019", "06_Floater", "141.37"],["09-30-2019", "07_Office", "246.91"],["09-30-2019", "08_Administration", "0.00"],["09-30-2019", "09_Director", "0.00"],["09-30-2019", "12_Kitchen", "0.00"],["10-01-2019", "00_Infants", "760.37"],["10-01-2019", "01_Ones", "756.48"],["10-01-2019", "02_Twos", "640.23"], ["10-01-2019", "03_Threes", "552.66"]];

attendance.forEach(a => {
  const department = departments.find(d => a[0] === d[0] && a[1] === d[1]);
  
  if (department) {
    a.push(parseFloat(department[2]));
  }
});

console.log(attendance);

Answer №2

In order to find the expense for a specific date and department in the attendance array, you can utilize the map() method along with the find() method.

If the expense is found, it will be appended; otherwise, the item remains unchanged.

var attendance = [ ["09-30-2019", "00_Infants", 22], ["09-30-2019", "01_Ones", 38], ["09-30-2019", "02_Twos", 40], ["09-30-2019", "03_Threes", 42], ["09-30-2019", "04_Fours", 19], ["10-01-2019", "00_Infants", 27], ["10-01-2019", "01_Ones", 42], ["10-01-2019", "02_Twos", 51] ];

var expenses = [ ["09-30-2019", "00_Infants", "584.56"], ["09-30-2019", "01_Ones", "701.51"], ["09-30-2019", "02_Twos", "614.02"], ["09-30-2019", "03_Threes", "442.50"], ["09-30-2019", "04_Fours", "166.65"], ["09-30-2019", "06_Floater", "141.37"], ["09-30-2019", "07_Office", "246.91"], ["09-30-2019", "08_Administration", "0.00"], ["09-30-2019", "09_Director", "0.00"], ["09-30-2019", "12_Kitchen", "0.00"], ["10-01-2019", "00_Infants", "760.37"], ["10-01-2019", "01_Ones", "756.48"], ["10-01-2019", "02_Twos", "640.23"], ["10-01-2019", "03_Threes", "552.66"] ];

var result = attendance.map(item => {
  let expense = expenses.find(expense => expense[0] === item[0] && expense[1] === item[1]);
  if (expense) {
    return [...item, expense[2]];
  } else {
    return item;
  }
});

console.log(result);

Answer №3

To organize these components, you can use a Map with a designated "key". In your scenario, the key could be the date and department. Here's how you can achieve this:

  • Create a mapping based on your expenses array.
  • Go through the attendance array, retrieve the expense associated with the matching key from the created grouping, and add the expense to that array.

const attendance = [
  ["09-30-2019", "00_Infants", 22],
  ["09-30-2019", "01_Ones", 38],
  ["09-30-2019", "02_Twos", 40],
  ["09-30-2019", "03_Threes", 42],
  ["09-30-2019", "04_Fours", 19],
  ["10-01-2019", "00_Infants", 27],
  ["10-01-2019", "01_Ones", 42],
  ["10-01-2019", "02_Twos", 51]
];
const expenses = [
  ["09-30-2019", "00_Infants", "584.56"],
  ["09-30-2019", "01_Ones", "701.51"],
  ["09-30-2019", "02_Twos", "614.02"],
  ["09-30-2019", "03_Threes", "442.50"],
  ["09-30-2019", "04_Fours", "166.65"],
  ["09-30-2019", "06_Floater", "141.37"],
  ["09-30-2019", "07_Office", "246.91"],
  ["09-30-2019", "08_Administration", "0.00"],
  ["09-30-2019", "09_Director", "0.00"],
  ["09-30-2019", "12_Kitchen", "0.00"],
  ["10-01-2019", "00_Infants", "760.37"],
  ["10-01-2019", "01_Ones", "756.48"],
  ["10-01-2019", "02_Twos", "640.23"],
  ["10-01-2019", "03_Threes", "552.66"]
];

const key = (date, department) => `${date};${department}`;
const expenseMap = new Map(expenses.map(([date, dept, expense]) => [key(date, dept), expense]));

attendance.forEach(a => a.push(expenseMap.get(key(a[0], a[1])));
console.log(attendance)

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

Easy method to create an array of increasing numbers in Swift such as 1, 3, 5

How can you create an array with a progressive series like the following: 1,3,5,... up to 99 What changes should be made to this code to achieve that? let arrayAP = Array(stride(from: 1, through: 99, by: 2)) // 1,3,..99 ...

unraveling JSON information in PHP through AJAX

I'm attempting to parse a JSON file using PHP and Ajax for posting. $.ajax({ type:'GET', url:'http://147.175.98.165/zadanie6/index.php/meniny/3', data:'{"stat":"Cesko","datum":" ...

Materialize CSS is throwing an error: 'velocity is not a function'

Encountering an issue with Materialize CSS. A JavaScript error appears 'I('.velocity is not a function', for certain actions. For instance, clicking the collapse icon on the sidenav results in e.velocity is not a function error. Similarly, u ...

The Dropdown Button Functions Once and Then Stops

I am facing a challenge in implementing a button within an HTML table that triggers a dropdown menu when clicked, and closes upon another click or when the user clicks outside the menu. Oddly, the button only seems to work once before completely losing fun ...

Tips for sending an array containing objects with an ID using Angular

Can you give me your thoughts on how to post an array with some object? This is the code I am working with: const selectedJobs = this.ms.selectedItems; if (!selectedJobs) { return; } const selectedJobsId = selectedJobs.map((jobsId) => ...

Timing of Bindings in AngularJS

In my setup, I have a controller that calls a service to retrieve a list of categories: $scope.enquiryCategories = CategoryServices.listCategories(); The service then fetches this data from an external API: listCategories: function () { return $http({ ...

When using v-for to render an array list fetched from AsyncData, an error is thrown: The virtual DOM tree rendered on the client-side does not match the one

For my application, I am utilizing Nuxt.js. On one of the pages, I am using AsyncData to fetch an array of data objects from my API asynchronously. These data objects are then rendered in my template using v-for. Everything is functioning properly until I ...

How to extract only the truthy keys from an object using Angular.js

I am looking to retrieve only the keys with a true value in the data object and display them in the console with the specified format: Object { Agent=true, Analytics / Business Intelligence=true, Architecture / Interior Design=false } The catego ...

PHP Command Line Interface can effectively parse JSON strings provided as arguments

When utilizing PHP 5.3 and passing a JSON encoded string as an argument via command line... /usr/local/bin/php -q /path/to/script.php {"key":"test","cache":1} ... the code within script.php looks like this: <?php print_r($argv); ?> The output is: ...

Can bumpbox be activated from flash?

I've spent a lot of time searching on Google without any success. I am trying to figure out how to make a FLV movie play in a bumpbox window when a button is clicked in a flash banner. Does anyone have any ideas? I attempted to find some guidance on ...

Tips for displaying a loader image with a centered message and preventing the bootstrap modal dialogue box from closing during an AJAX response from a PHP file

I am using Bootstrap version 3.0.0. Below is the HTML code for a Bootstrap Modal: <div class="modal fade" id="newModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> < ...

Task allocation is encountering issues with the implementation of a multidimensional array

Attempting to structure an array in a specific format, I am struggling to achieve the desired result. Any assistance in updating my answer would be greatly appreciated. print_r($productsArray) Array ( [0] => Array ( [a ...

jQuery does not change the scroll position of elements

I'm looking to implement a feature on my website where certain points act as "magnets" and when the user is near one of these points, the window automatically scrolls to the top. I found a jQuery plugin that does something similar which you can check ...

Issues with previewing PDF files in AngularJS

I am trying to display a PDF preview on my website using the following code: var $scope; angular.module('miniapp', ['phonecatFilters', 'ngSanitize']); function Ctrl($scope) { $scope.test = 'Example from: '; ...

Remove the preset text in an input field by clicking on it

Looking for help: <input name="Email" type="text" id="Email" value="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92f7fff3fbfed2f3f0f1bcf7eaf3ffe2fef7">[email protected]</a>& ...

What are the methods for differentiating between a deliberate user click and a click triggered by JavaScript?

Social media platforms like Facebook and Twitter offer buttons such as Like and Follow to allow users to easily engage with content. For example, on Mashable.com, there is a Follow button that, when clicked, automatically makes the user follow Mashable&ap ...

What is the best way to implement <li> in place of <div> to ensure the tool-tip code functions properly?

To see an example, please refer to this fiddle: http://jsfiddle.net/66nLy/12/ I am looking to achieve a similar functionality on a webpage, but using <li> instead of <div>. Here is the HTML code snippet: <table class="base-table selection- ...

Assigning values to jagged arrays in a class

Having difficulty grasping the concept of creating a jagged array in C#. In the code provided below, it compiles without any issues. However, if I were to move the lines that assign values to the array "places" from within the method to within the class it ...

Leveraging global attributes beyond Vue components - Vue 3

I have created custom service instances in main.ts app.config.globalProperties.$service1 = new Service1(); app.config.globalProperties.$service2 = new Service2(); While I can use these instances inside Vue components, I also want to be able to utilize the ...

The JQuery script has not been initialized, causing the function to not activate

I keep encountering this error message: Uncaught ReferenceError: toggleOptionsVisibility is not defined at HTMLSelectElement.onchange Here's the HTML code I'm working with: <div> <label asp-for="Type"></label&g ...