Iterating through an array of objects and performing reduction based on various key-value pairs

I am faced with a challenge of consolidating a large array of objects into one single array that has a specific structure. Each item, such as a banana, needs to be present in two separate objects for buy orders and sell orders, each with their own distinct price and data.

I attempted to identify the unique pairings of items (banana, apple, orange, etc.) and loop through them, while also nesting another map function for the data processing, but I have not been able to find a solution yet.

let uniquePairing = Array.from([...new Set(data.map(item => item["name"]))])


**let data = [{
name:'banana,
price:( average cost)
type:buy
items: ( total bananas)
fee: ( total fees)
},
{
name:'banana,
price:( average cost)
type:sell
items: ( total bananas)
fee: ( total fees)
},
{ apples...
]**

Example of data

let data = [
{
name:"banana",
price:1,
type: "buy",
fee: 0.5,
items:25
},
{
name:"banana",
price:1.2,
type: "buy",
fee: 0.5,
items:25
},
{
name:"banana",
price:2,
type: "sell",
fee: 0.5,
items:25
},
{
name:"apple",
price:1,
type: "buy"
fee: 0.5
items:25
},
{
name:"apple",
price:1.2,
type: "buy",
fee: 0.5,
items:25
},
{
name:"apple",
price:2,
type: "sell",
fee: 0.5,
items:25
}
]

Answer №1

It seems like you're looking for a solution using the reduce function:

const uniqueItems = data.reduce((accumulator, currentItem) => {
  const name = currentItem.name,
        type = currentItem.type;

  let matchedItem = accumulator.find(item => item.name === name && item.type === type);
  
  if (!matchedItem) {
    accumulator.push({
      ...currentItem,
      totalPrice: currentItem.price,
      objCount: 1
    });
  } else {
    matchedItem.totalPrice += currentItem.price;
    matchedItem.objCount++;
    matchedItem.price = matchedItem.totalPrice / matchedItem.objCount;
    matchedItem.items += currentItem.items;
    matchedItem.fee += currentItem.fee;
  }

  return accumulator;
}, []);

Answer №2

One way to achieve this is by following the steps below:

   let collection = [
{
name:"banana",
price:1,
type: "buy",
fee: 0.5,
items:25
},
{
name:"banana",
price:1.2,
type: "buy",
fee: 0.5,
items:25
},
{
name:"banana",
price:2,
type: "sell",
fee: 0.5,
items:25
},
{
name:"apple",
price:1,
type: "buy",
fee: 0.5,
items:25
},
{
name:"apple",
price:1.2,
type: "buy",
fee: 0.5,
items:25
},
{
name:"apple",
price:2,
type: "sell",
fee: 0.5,
items:25
}
]

const getFruitDetails = (fruits, fruit) => fruits.filter(fr=> fr.name===fruit.name && fr.type=== fruit.type)

const calculateTotal = (fruits, field) => fruits.reduce((acc,cur)=> acc+=cur[field], 0)

const checkIfRegistered = (fruits, value) => fruits.some(fruit=> fruit.type === value.type && fruit.name===value.name)

const extractFruits = (fruits) => {
  return fruits.reduce((acc, cur)=> {
if(checkIfRegistered(acc, cur)){
  return acc
}
acc.push({name: cur.name, type: cur.type})
return acc
  }, [])
}

function mergeCollection(arr){
  const fruits = extractFruits(arr)
  return fruits.map(fruit=> {
const data = getFruitDetails(arr, fruit)
return {
  name: fruit.name,
  price: calculateTotal(data, "price"),
  type: fruit.type,
  fee: calculateTotal(data, "fee"),
  items: calculateTotal(data, "items")
}
  })
}

console.log(mergeCollection(collection))

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

Likelihood of triggering a function based on percentage

Hey everyone, I'm looking to add some randomness to the buttons on my website. I have a Button that could activate function one, function two or function three. However, I want to make it so there is a 60% chance that function one gets called from the ...

Having trouble viewing the page of a new package you published on the NPM Website?

Today, I officially released an NPM package called jhp-serve. It can be easily installed using npm install or run with npx. You can even find it in the search results here: https://www.npmjs.com/search?q=jhp. However, when attempting to view its page by cl ...

Implementing external JavaScript files such as Bootstrap and jQuery into a ReactJS application

Just diving into ReactJs, I've got static files like bootstrap.min.js, jquery.min.js, and more in my assets folder. Trying to incorporate them into my ReactJs App but running into issues. Added the code below to my index.html file, however it's ...

What is the best way to determine the operational schedule of online stores that have varying business days?

Struggling to automatically calculate the working days for various online stores that operate on different schedules. The challenge lies in some of these stores being open on weekends. It's important to note that JavaScript starts counting days of the ...

When using Array.prototype.map(callback, thisArg), the second parameter is disregarded

Currently, I am developing a small game using Node.js and aiming to offer support for two different languages. To display the translated lists of various game modes along with their descriptions, I have implemented Array.prototype.map(callback, thisArg). ...

JavaScript code to change an array into a stringified format

I have encountered a challenge with transforming an array. The original array looks like this: array = [ { "name": "name", "value": "Olá" }, { "name": "age" ...

Drop the <span> element into a paragraph by utilizing JQuery's drag and drop feature

Trying to drag and drop <span> into <p>. The code is functional, but encountering 3 issues: When editing content inside <p> by typing (e.g. three words) and then dragging <span> into <p>, the newly typed words are consider ...

Troubleshooting Cross-Origin Read Blocking with the Google Maps Elevation API using Axios in a Vue.js Application

I'm currently working on integrating the Google Maps API into a Vue.js project. I've encountered an issue with two Google Maps services: - The Time Zone API is functioning properly. - However, the Elevation API is giving me a Cross-Origin Read Bl ...

Angular7 & Electron: Resolving the Issue of Loading Local Resources

I am encountering difficulties while working with electron. Although I can successfully load my project using ng serve, I encounter an error when attempting to open it with electron as shown in the developer tools Not allowed to load local resource: fil ...

Finding the index of a nested div element with a click event using jQuery

I'm currently working on a click event to retrieve the index of the outermost parent div, but I'm facing some difficulties in getting it to work. Here is a snippet showcasing a list of several divs: <div class="owl-item"> <div class= ...

Create a dynamic select2 field based on the value selected in another dropdown menu

Starting with an initial dropdown where a value needs to be selected: <select id="indexID" name="indexID" class="form-control" onChange="updateSector();" style="width:300px;"> <option value='' selected>Choose an Index</option> ...

ESLint and Prettier are butting heads when trying to run their commands consecutively

My package.json file includes two commands: "format": "prettier --write \"{src,{tests,mocks}}/**/*.{js,ts,vue}\"", "lint": "eslint . -c .eslintrc.js --rulesdir eslint-internal-rules/ --ext .ts,.js,.vue ...

eliminate the firebase firestore query using onSnapshot

Seeking assistance with the following code snippet: firebase.firestore() .collection("chatrooms") .doc(`${chatId}`) .collection(`${chatId}`) .orderBy("timestamp") .limit(50).onSnapshot((snapshot) => { //performing oper ...

Creating a Typescript interface for a anonymous function being passed into a React component

I have been exploring the use of Typescript in conjunction with React functional components, particularly when utilizing a Bootstrap modal component. I encountered some confusion regarding how to properly define the Typescript interface for the component w ...

What is the best way to conceal a menu that automatically scrolls to the content when it is clicked?

Below is a Codepen with a menu that isn't behaving as expected. var menu = document.querySelector('.nav__list'); var burger = document.querySelector('.burger'); var doc = $(document); var l = $('.scrolly'); var panel = $ ...

"Experiencing a problem with Next.js 13 where the User Context is not functioning properly outside of _app

When using Next.js 13 and the user context, I've noticed that it doesn't function properly outside of _app.tsx. Any idea why? src>context>UserPositionContext.tsx import { createContext, useContext, useState } from "react"; const ...

The contact form displays a confirmation message indicating successful submission, however, it fails to actually send the email

Having issues with a PHP script I created for the contact page on my website. After a user fills out and submits the form, they see a success message but the email is not sent. Can someone review this script and point out where I went wrong? <?php ...

javascript string assignment

Is it possible to conditionally assign a string based on the result of a certain condition, but for some reason, it's not working? var message = ""; if (true) { message += "true"; } else { message += "false" } console.log(message); ...

The dialog box is not taking up the full width of the browser window

I'm facing an issue with a dialog box that only occupies a portion of the browser width, despite having a width set to 100%. The backdrop, however, extends across the entire width. //App.js import React from "react"; import ConfirmationDial ...

Changing route parameters or query parameters does not trigger a reload of component data in React

The "home" component has links that direct to the product component when clicked. Another component always visible displays links to recently visited products. However, on a product page, these links fail to work properly. Although the URL updates and tri ...