Minimize the frequency of using map and filter together when operating on arrays of objects

When given an array of objects as input, the task is to identify and subtract the `transactionAmount` field value of an item that shares the same `transactionReference` (as the current item in a loop) and has a `transactionType` of 13. The final result should exclude the items with `transactionType` of 13 and perform custom actions on the remaining items.

Consider the following array:

[
    {
        transactionId: 45194,
        transactionDate: 1579858773136,
        transactionType: 13,
        transactionReference: 82941,
        transactionAmount: 1.21
    },
    {
        transactionId: 45193,
        transactionDate: 1579858773120,
        transactionType: 11,
        transactionReference: 82941,
        transactionAmount: 10
    },
    {
        transactionId: 45192,
        transactionDate: 1579858763947,
        transactionType: 1,
        transactionAmount: 10
    },
    {
        transactionId: 45191,
        transactionDate: 1579858759085,
        transactionType: 131,
        transactionAmount: 2000
    }
]

The function I have designed for this purpose is as follows:

transactions => transactions
    .map(({
      transactionId,
      transactionDate,
      transactionType,
      transactionReference,
      transactionAmount
    }) => ({
      transactionId,
      transactionDate,
      transactionType,
      transactionReference,
      transactionAmount: transactionAmount - Number(transactions
        .filter(({
          transactionId: _transactionId,
          transactionReference: _transactionReference,
          transactionType
        }) => transactionType === 13 &&
        _transactionId !== transactionId &&
        transactionReference&&
        _transactionReference === transactionReference
        )
        .map(({ transactionAmount }) => transactionAmount))
    }))
    .filter(({ transactionType }) => transactionType !== 13)
    .map(({
      transactionId,
      transactionAmount,
      transactionDate,
      transactionType
    }) => ({
      id: transactionId,
      amount: Number(transactionAmount).toFixed(2),
      date: moment(transactionDate).format('H:mm'),
      type: transactionType
    }))

My goal now is to optimize this function by reducing the number of map/filter functions used while maintaining the desired outcome.

The resulting modified array is shown below:

[
    {
        id: 45193,
        amount: "8.79",
        date: 1579858773120,
        type: 11
    },
    {

        id: 45192,
        amount: "10.00",
        date: 1579858763947,
        type: 1

    },
    {
        id: 45191,
        amount: "2000.00",
        date: 1579858759085,
        type: 131
    }
]

Answer №1

When organizing your array, make sure transactions with type 13 are prioritized (*)

  • Create a map linking references to amounts initially
  • Omit transactions of type 13 from the result
  • For remaining transactions, subtract the corresponding amount from the map (or subtract 0 if not found)

const transactions = [{"transactionId":24578,"transactionDate":1579858773136,"transactionType":13,"transactionReference":82941,"transactionAmount":1.21},{"transactionId":24577,"transactionDate":1579858773120,"transactionType":11,"transactionReference":82941,"transactionAmount":10},{"transactionId":24576,"transactionDate":1579858763947,"transactionType":1,"transactionAmount":10},{"transactionId":24575,"transactionDate":1579858759085,"transactionType":131,"transactionAmount":2000}]
const output = transactions.map(trans => {
  const ref = trans.transactionReference
  return Object.assign({
    root: trans,
    date: trans.transactionDate,
    type: trans.transactionType,
    id: trans.transactionId,
    amount: trans.transactionAmount
  }, ref ? { ref } : {})
})
.reduce((output, trans) => {
  if (trans.type === 13) {
    output.refAmount[trans.ref] = trans.amount
    return output
  }

  const deductedAmount = trans.amount - (output.refAmount[trans.ref] || 0)
  output.non13.push({
    id: trans.id,
    amount: deductedAmount,
    date: new Date(trans.date).getTime(),
    type: trans.type
  })
  return output
}, {refAmount: {}, non13: []}).non13
 
 console.log(output)

(*) If unsorted, perform sorting as indicated below

transactions.sort((x, y) => -(x.transactionType == 13))

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

Adjust the CSS within a <style> element using jQuery or javascript

What I aim to accomplish: I intend to dynamically add and modify rules within a <style> tag using JavaScript/jQuery. Reason behind this goal: I am in the process of creating a color scheme editor where changes made by the user should be reflected ...

What is the process for transforming the values brought in by ImportJSON into numeric values?

After some investigation, I've come to realize that values brought into Google Spreadsheets using ImportJSON are actually considered as text rather than numeric. As a result, they cannot be easily summed up. Is there a way to convert these values int ...

Reverberating the correct array index repeatedly

I have successfully completed this exercise using the code below, but I believe there is a more efficient way to achieve the same result without using multiple if loops. Perhaps, it can be done using a foreach loop... `<?php if (in_array($numbe ...

Tips for showing error messages in response to exceptions

My function is supposed to display the response text that comes back from ex.responseText. However, every time I attempt it, it returns as "undefined" even though the text is there. onError: function (ex) { $('<div>' + ex._message + &a ...

Obtain the chosen value from a dropdown menu in a React child component

Invoking the child component named comboBox. I am a newcomer to React and facing an issue while trying to pass data from a child component to the Parent component. Despite attempting various methods involving functions in both components, I have only come ...

Tips for adjusting column sizes in ag-grid

I'm a beginner with ag-grid and need some help. In the screenshot provided, I have 4 columns initially. However, once I remove column 3 (test3), there is empty space on the right indicating that a column is missing. How can I make sure that when a col ...

Tips for accessing a component method in React from a WebSocket callback

Struggling with Javascript and React here. The goal is to update a component's state using push messages from a WebSocket. The issue lies in calling the function handlePushMessage from the WebSocket callback. Here's the code snippet: const Main ...

Refresh the jQuery Carousel when the window is resized to switch the orientation from vertical to horizontal

I am in the process of creating a gallery for a responsive layout, utilizing jQuery Riding Carousels for the thumbnails. You can find more information about it here. One issue I am encountering is that when the window size shrinks to be smaller than 1024p ...

Is it possible to have both Node.js and browser code in the same file using webpack, while ensuring that only the browser code is accessible and the Node.js code remains hidden?

I need to work with a file that contains both Node.js and browser code. It's crucial that the Node.js code remains hidden when running in the browser environment. Is it possible for Webpack to exclude specific sections of the code based on the enviro ...

Tips for resizing a Numpy array using zero padding

I am facing a challenge with reshaping a Numpy array. The current array looks like: array([1, 2, 3, 4, 5, 6, 7, 8]) My goal is to reshape it into an array that resembles: array([[5, 0, 0, 6], [0, 1, 2, 0], [0, 3, 4, 0], [7, 0, 0, 8] ...

Angular Material: Enhanced search input with a universal clear button

After searching for a cross-browser search control with a clear button similar to HTML5, I found the solution rendered by Chrome: <input type="search> The code that gave me the most relevant results can be found here. I used the standard sample w ...

What is the best way to display a single div at a time?

I have a setup with three sections, each containing two divs. The first div has a button that, when clicked, should open the next div while closing any other open div. However, I am facing an issue where clicking the button again does not close the corresp ...

Adding a class to a clicked button in Vue.js

A unique function of the code below is showcasing various products by brand. When a user clicks on a brand's button, it will display the corresponding products. This feature works seamlessly; however, I have implemented a filter on the brands' lo ...

Ways to create loops in Excel without using macros

Sorry for repeating the question, but I am unable to comment due to lack of reputation. I am faced with a similar query as How to loop in excel without VBA or macros?, however, I need to explore recursive loops in Excel without macros for a slightly differ ...

Delay loading background image until a specific time has passed, preventing website from fully loading

My website features a vibrant backgroundImage Slideshow that functions seamlessly. However, I am looking to reload the images of the slideshow after a specific time interval. The issue is that the website keeps loading endlessly. Once the website has com ...

Execute the PHP POST request to query "SELECT * FROM .... WHERE ..."

Trying to send a user's ID from my Android app to retrieve their information from the SQLite database on the server using the $_POST method request. Following tutorials, I learned that mysqli_query() will return an Object for a successful SELECT query ...

Can we include an option to display all pages in one row on a single page?

Is it possible to include an option to display all rows alongside the current options of 10, 15, and 100? I've been unable to locate this feature in the documentation: Check out the Codesandbox example: https://codesandbox.io/s/muidatatables-custom-t ...

Creating a persistent toolbar in Vuetify: Tips and tricks

Within my Vuetify app, I've implemented a toolbar: <v-toolbar dark color="primary"> <v-toolbar-side-icon @click.stop="drawer.drawer = !drawer.drawer"></v-toolbar-side-icon> <v-toolbar-title>{{drawer.title}}</v-toolb ...

Avoiding conflicts among jquery prototype/plugin methods

Imagine I have a primary JavaScript file on my website that includes the following code: $.fn.extend({ break: function(){ // Add your custom code here }, cut: function(){ // More code here }, // ...and many other methods }); When using t ...

Using Javascript to access the variables of a parent function

I have the following simplified code snippet: function(req, res) { var path = 'login'; req.on('end', function(data) { var post = parsevars(rawpost, '&'); if (typeof post.username !== 'undefined' && type ...