Pair two arrays based on a specific key value

I'm currently facing a challenge where I need to associate two arrays of objects, and I could really use some help with this. Explanation :

One array contains various reference products

const array1 = [
{name: peanuts, referenceKey: 0}, 
{name: almond, referenceKey: 1}, 
{name: nuts, referenceKey: 2}, 
{name: cream, referenceKey: 3}
] 

The second array consists of open reference products with expiration dates and matching reference keys from array1, along with specific keys for each open product

const array2 = [
 {name: peanuts, expirationDate: "30d", referenceKey:0, otherKey: 42}, 
 {name: peanuts, expirationDate: "20d", referenceKey:0, otherKey: 43}, 
 {name: peanuts, expirationDate: "15h", referenceKey:0, otherKey: 44}, 
 {name: almond, expirationDate: "30d", referenceKey:1, otherKey: 45},
 {name: cream, expirationDate: "1d", referenceKey: 3, otherKey: 46},
 {name:cream, expirationDate: "12h", referenceKey: 3, otherKey: 47}
] 

My goal is to calculate the number of the same products in array2 that are open, and store this count in a new array based on array1, like so:

const array3 = [
 {name: peanuts, referenceKey: 0, opened: 3}, 
 {name: almond, referenceKey: 1, opened: 1}, 
 {name: nuts, referenceKey: 2, opened: 0}, 
 {name: cream, referenceKey: 3, opened: 2}
] 

I attempted to group array2 by name using the Reduce() method as shown below :

    const groupByName = (products, name) => {
        return products.reduce((acc, obj) => {
            var key = obj[name];
            if (!acc[key]) {
                acc[key] = []
            }
            acc[key].push(obj);
            return acc
        }, [])
    };

    const groupByName = groupByReference(array2, "name")
    console.log(groupByName)
    

output of groupByName:

  [
    [peanuts:
    [
        {name: peanuts, expirationDate: "30d", referenceKey: 0, otherKey: 42}, 
        {name: peanuts, expirationDate: "20d", referenceKey:0, otherKey: 43}, 
        {name: peanuts, expirationDate: "15h", referenceKey:0, otherKey: 44}, 
    ],
    cream: [
        {name: cream, expirationDate: "1d", referenceKey: 3, otherKey: 46 },
        {name: cream, expirationDate: "12h", referenceKey: 3, otherKey: 47}
    ],
    almond: [
        {name: almond, expirationDate: "30d", referenceKey:1, otherKey: 45},
    ]
 ]

Next, I tried to determine the length of each array but faced difficulties. Despite attempting to utilize the Map() method, it did not provide me with the expected results.

Even when explicitly mentioning an index like groupByName['peanuts'], the console.log() returned the correct array. However, trying to access groupByName['peanuts'].length did not work as intended.

Answer №1

To achieve the desired output and keep track of duplicate objects with the same name, you can utilize an object in your code logic.

const
    items1 = [{ name: "peanuts", identifier: 0 }, { name: "almond", identifier: 1 }, { name: "nuts", identifier: 2 }, { name: "cream", identifier: 3 }],
    items2 = [{ name: "peanuts", expiry: "30d", identifier: 0, key: 42 }, { name: "peanuts", expiry: "20d", identifier: 0, key: 43 }, { name: "peanuts", expiry: "15h", identifier: 0, key: 44 }, { name: "almond", expiry: "30d", identifier: 1, key: 45 }, { name: "cream", expiry: "1d", identifier: 3, key: 46 }, { name: "cream", expiry: "12h", identifier: 3, key: 47 }],
    tempObject = {},
    resultSet = items1.map(obj => tempObject[obj.name] = { ...obj, count: 0 });

items2.forEach(obj => tempObject[obj.name].count++);

console.log(resultSet);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

const newArr = [...originalArr];
for (let item of newArr) {
  item['status'] = referenceArr.filter(el => el.key === item.key).length;
}

Answer №3

Based on your initial request, I believe this is the solution you are looking for if I have interpreted your question correctly.

You have the option to group by either name or referenceKey since they are present in both arrays, but not by expirationDate.

const array1 = [
  { name: "apples", referenceKey: 0 },
  { name: "bananas", referenceKey: 1 },
  { name: "oranges", referenceKey: 2 },
  { name: "pears", referenceKey: 3 },
];

const array2 = [
  { name: "apples", expirationDate: "5d", referenceKey: 0, quantity: 4 },
  { name: "apples", expirationDate: "3d", referenceKey: 0, quantity: 5 },
  { name: "apples", expirationDate: "8h", referenceKey: 0, quantity: 6 },
  { name: "bananas", expirationDate: "7d", referenceKey: 1, quantity: 7 },
  { name: "pears", expirationDate: "1d", referenceKey: 3, quantity: 8 },
  { name: "pears", expirationDate: "20h", referenceKey: 3, quantity: 9 },
];

const groupByKey = (fruits, instances, key) => {
  return fruits.reduce((acc, obj) => {
    // Count instances that match
    const matching = instances.filter((instance) => instance[key] === obj[key])
      .length;

    // Add to accumulator array using spread operator for immutability.
    acc = [
      ...acc,
      {
        name: obj.name,
        referenceKey: obj.referenceKey,
        matching,
      },
    ];

    return acc;
  }, []);
};

const array3 = groupByKey(array1, array2, "name");
console.log(array3);

Answer №4

To kick things off, I suggest implementing a helper function that tallies all objects containing a specific value when a provided function is applied to them. Here's an example:

countItemsByAttribute(x => x.name)([{name: 'apple', type: 'fruit'}, {name: 'orange', type: 'fruit'}, 
                     {name: 'apple', type: 'fruit'}, {name: 'banana', type: 'fruit'}])
//=> {apple: 2, orange: 1, banana: 1}

This helps us count our objects based on their category (if type is intended to be a string and not reference). Then we can easily loop through our object definitions, incorporating the relevant quantity property from the result (or defaulting to 0 if none found.)

The implementation could resemble this:

const countItemsByAttribute = (fn) => (items) => 
  items.reduce((acc, item, _, __, key = fn(item)) => ({...acc, [key]: (acc[key] || 0) + 1}), {})

const quantity = (definitions, instances, counts = countItemsByAttribute (x => x.category) (instances)) =>
  definitions.map(def => ({...def, quantity: counts[def.category] || 0}))

const productArray = [{product: 'apple', category: 0}, {product: 'orange', category: 1}, {product: 'banana', category: 2}, {product: 'grapefruit', category: 3}]
const inventoryArray = [{product: 'apple', quantityInStock: 10, category: 0}, {product: 'apple', quantityInStock: 5, category: 0}, {product: 'banana', quantityInStock: 20, category: 1}] 

console.log(quantity(productArray, inventoryArray))
.as-console-wrapper {max-height: 100% !important; top: 0}


Your idea was definitely heading in the right direction. You could make use of your groupProducts (after resolving a naming conflict between two versions of groupProducts and one of groupByCategory) with a method similar to this:

const groupedByProduct = groupProducts(inventoryArray, "product")

productArray.map(({product, ...rest}) => ({
  product, 
  ...rest, 
  quantity: (groupedByProduct[product] || []).length
}))

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

Adjusting editable property in FullCalendar during script execution

Currently, I am working with Angular JS and fullCalendar to customize the functionality of my calendar. My goal is to change the editable property of the calendar when a button is clicked. Although it seems like a straightforward task, I am facing difficul ...

Obtain the final timestamp in the array

I am facing an issue with my array. How can I retrieve the latest time from the array? Below is a sample of my code: Array ( [0] => 2015-08-04 01:00:00 [1] => 2015-08-03 16:00:00 [2] => 2015-08-03 10:00:00 ) This is just a glimpse of ...

Tips for Retrieving the Key Names of JSON Objects within a JSON Array

I'm trying to retrieve the object names "channelA" and "channelB". Here is the JSON data: [ { "channelA": { "programmes": [ { "start_utc": 1522208700, "stop_utc": 152220 ...

What is the best way to transform JSON or an array from an AJAX responseText into a JavaScript array?

I recently implemented ajax into my code, and it is working perfectly. It provides me with either JSON or an array as the output. Here is the snippet of code I used: xmlhttp=new XMLHttpRequest(); xmlhttp.open("GET","http://map_ajax_control.php",false); xm ...

The JSON data sent from the primary Electron process is arriving as undefined in the renderer

Currently delving into an Electron project to explore the technology. It's been a captivating and enjoyable experience so far as I work on creating a basic home controller for my IoT devices. However, I've encountered a minor issue. In my main.js ...

Issue with PLUploader in ASP.Net/JQuery: "Add Files" button not functioning post image upload操作

Hello, I've been utilizing the PLUploader controller for ASP.NET in C#. Initially, it works as intended, but after uploading files, the "add files" button becomes disabled or stops working, preventing me from adding more images. Can anyone offer assi ...

Is there a way to alter the color of options within a select tag when hovering the mouse over them

After searching through multiple websites, I couldn't find a solution on how to change the option background color on hover from blue to green. The screenshot provided below illustrates what I am requesting for in a clearer manner. I attempted to use ...

React component fails to display content following execution of Jquery Ajax request

Utilizing a basic jQuery ajax function to retrieve inline HTML code from an API $.ajax({ url: url, headers: { 'Accept': 'application/javascript' }, dataType: 'html', beforeSend: function(){ $('.load-mor ...

Iterate through an array to dynamically assign values to variables using string elements

I'm facing a challenge here. I need to generate 4 new elements with the same class but different IDs without repeating code. Unfortunately, my loop doesn't seem to be working as expected. I've spent the last 2 hours trying to crack this puz ...

Excessive Function Calls Detected in AngularJS Application

I'm facing a major performance issue. I need to display details in a list, but the function is being called excessively. Feel free to check out the demo here Here's the HTML code snippet : <div ng-controller="MyCtrl as ctrl"> <p>K ...

Exploring the capabilities of dynamic pathname routing in Next.js

Consider this scenario: there is a path that reaches me as /example/123 and I must redirect it to /otherExample/123. My code utilizes next/router, extracting the URL from router.asPath. if(router.asPath == '/example/123') { Router.push(' ...

Store the value returned by the function(data) from the $.post method in a variable

Hello Fellow Developers! I'm currently working on a coding project with the following objective: My goal is to extract URLs of files stored in a specific folder and then store them in an array using JavaScript. Here's how I envision the proces ...

What could be causing my ng-grid footer to refuse to align with the bottom border?

Currently utilizing ng-grid and various AngularJS UI Bootstrap components on my website, I have encountered a recurring issue. By diligently investigating, I have successfully replicated the problem. Access the Plunker demonstration through this link. The ...

The $http Service encounters a failure with an unknown status code

Difficulty Integrating AngularJS, jQuery, and Adobe Panel Creation I recently updated the versions of AngularJS and jQuery for my project. Previously, I was using jquery-1.11.0.min.js and AngularJS 1.2.10. Now, I want to utilize the latest available versi ...

Encountering an issue with MUI 5 where it is unable to access properties of undefined when utilizing makestyles

I recently finished building a react app using MUI-5 and everything was running smoothly. However, I've encountered a strange issue where my app refuses to start and I'm bombarded with multiple MUI errors. These errors started popping up after I ...

Show the elements of an array (that have been read and processed from a text file) on separate lines using JavaScript

Hello, I have the code below where a user can upload a text file. I attempted to display the output in a div after splitting it using the @ character. The array elements stored in variables are correctly displayed with new lines in an alert, but they are p ...

Oops! Looks like we have encountered an issue with reading the property 'checked' of nothing

Whenever I click the checkbox, an image should be displayed. Unfortunately, I encountered an error: Uncaught TypeError: Cannot read property 'checked' of null at (index):185 at dispatch (VM576 jquery.min.js:3) at i (VM5 ...

What is the procedure for matching paths containing /lang using the express middleware?

I need to target paths that contain /lang? in the URL, but I am unsure how to specifically target paths that begin with /lang? I have two routes: app.get('/lang?..... app.get('/bottle/lang?....... I want to target these routes using app.use(&a ...

Using a bytearray for MD5 hashing in Python 2.6: A step-by-step guide

Python versions 2.7 and 3.4 have the capability to perform the following code snippet: import hashlib m = hashlib.md5() m.update(bytearray(128)) However, Python 2.6 will throw an error message: m.update(bytearray(128)) TypeError: update() argumen ...

Incorporate the casper function within the casper.evaluate() method

Is it possible to use the casper function inside casper.evaluate() with jQuery code? I need to iterate through elements in a way similar to how jQuery does. I have loaded the jquery.js library. Here is the script I have tried: casper.evaluate(function() ...