What is the best way to generate an array of objects by extracting specific properties from another array object?

Here is the information provided:

const cocktail = [
    {
        "idDrink":"13070",
        "strDrink":"Fahrenheit 5000",
        "strGlass":"Shot glass",
        "strInstructions":"Cover bottom of shot gla",
        "strIngredient1":"Firewater",
        "strIngredient2":"Absolut Peppar",
        "strIngredient3":"Tabasco sauce",
        "strIngredient4":null,
        "strMeasure1":"1/2 oz ",
        "strMeasure2":"1/2 oz ",
        "strMeasure3":"1 dash ",
        "strMeasure4":null
    }
]

I aim to create an array of objects that include only the non-null values from each strMeasure[n] and strIngredient[n]:

[
    {
        strMeasure1: value,
        strIngredient1: value
    },
    {
        strMeasure2: value,
        strIngredient2: value
    },
    …
]

Given the above cocktail array, the desired output would be:

[
    {
        measure: '1/2 oz',
        name: 'Firewater'
    },
    {
        measure: '1/2 oz',
        name: 'Absolut Peppar'
    },
    {
        measure: '1 dash',
        name: 'Tobasco sauce'
    },
]

Answer №1

Here is the solution:

Follow these steps:

  • Object.entries(cocktail[0]) will give you an array of [key, value] pairs from the data
  • Use filter to extract Ingredients and Measures while ignoring those with null values
  • Then, use reduce to construct the final array

For example:

const cocktail = [
    {
        "idDrink":"13070",
        "strDrink":"Fahrenheit 5000",
        "strGlass":"Shot glass",
        "strInstructions":"Cover bottom of shot gla",
        "strIngredient1":"Firewater",
        "strIngredient2":"Absolut Peppar",
        "strIngredient3":"Tabasco sauce",
        "strIngredient4":null,
        "strMeasure1":"1/2 oz ",
        "strMeasure2":"1/2 oz ",
        "strMeasure3":"1 dash ",
        "strMeasure4":null
    }
]
const result = Object.entries(cocktail[0])
.filter(([k,v])=>v && k.match(/^str(Ingredient|Measure)\d+$/))
.reduce((acc, [k, v]) => {
    const [t, n] = k.match(/^str(Ingredient|Measure)(\d+)$/).slice(1);
    acc[n-1] = {...acc[n-1], [t]:v};
    return acc;
}, [])
console.log(result);

You can also achieve this without the filter step

const result = Object.entries(cocktail[0])
.reduce((acc, [k, v]) => {
    if (v) {
        const [t, n] = k.match(/^str(Ingredient|Measure)(\d+)$/)?.slice(1) ?? [] ;
        acc[n-1] = {...acc[n-1], [t]:v};
    }
    return acc;
}, [])
console.log(result);

Answer №2

If you're looking to enhance your code by utilizing the map() method in JavaScript to extract specific key-value pairs from an object within an array, there are multiple approaches you can take. One option is using dot notation to access the desired values within the object. For more in-depth guidance on how to implement these techniques effectively, I've included some valuable resources below:

Extracting value of a property as an array from an array of objects

Converting array of objects to array of values in JavaScript

Tutorial on working with arrays of objects in JavaScript

Answer №3

To begin, create an array of objects containing a 'measure' and 'id' key-value pair. Next, utilize the 'id' to retrieve the corresponding value from the cocktail array.

const cocktail = [{
  "idDrink": "13070",
  "strDrink": "Fahrenheit 5000",
  "strGlass": "Shot glass",
  "strInstructions": "Cover bottom of shot gla",
  "strIngredient1": "Firewater",
  "strIngredient2": "Absolut Peppar",
  "strIngredient3": "Tabasco sauce",
  "strIngredient4": null,
  "strMeasure1": "1/2 oz ",
  "strMeasure2": "1/2 oz ",
  "strMeasure3": "1 dash ",
  "strMeasure4": null
}]
const obj = [];
for (let keys in cocktail[0]) {

  if (keys.includes('strIngredient')) {
    const tempObj = {
      measure: cocktail[0][keys],
      id: keys.charAt(keys.length - 1)
    }
    obj.push(tempObj)
  }
}
obj.forEach((elem) => elem.value = cocktail[0][`strMeasure${elem.id}`])
console.log(obj)

Answer №4

Lodash would be great

const drinkRecipe = {"idDrink":"13070","strDrink":"Fahrenheit 5000","strGlass":"Shot glass","strInstructions":"Cover bottom of shot gla","strIngredient1":"Firewater","strIngredient2":"Absolut Peppar","strIngredient3":"Tabasco sauce","strIngredient4":null,"strMeasure1":"1/2 oz ","strMeasure2":"1/2 oz ","strMeasure3":"1 dash ","strMeasure4":null};
    
const findKey = (string) => [...string.matchAll(/(strIngredient|strMeasure)(\d+)/g)].flat();
  
const mapping = { strIngredient: 'name', strMeasure: 'measure' };

const iterator = (acc, value, key) => {
    const [,  keyName, keyNumber] = findKey(key);
    if (value && keyName) {
      acc[keyNumber] ??= {};
      acc[keyNumber][mapping[keyName]] = value;
    }
    return acc;
};

const outputResult = _(drinkRecipe).transform(iterator, {}).values();

console.log(outputResult);
.as-console-wrapper { max-height: 100% !important; top: 0 }
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="127e7d7673617a52263c23253c2023">[email protected</a>/lodash.min.js"></script>

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

Steps to refresh a variable when the SMS read plugin successfully completes

I'm attempting to make a post call within the success callback of my SMS read plugin code. I can successfully print _this.otpnumber in the console. Please refer to my stack trace image link getSMS(){ var _this= this; var fil ...

Acquire the value of ant-design Select dropdown upon hover

How can we detect the selected option in an ant-design dropdown when it is hovered? <Select defaultValue="lucy" style={{ width: 120 }} onChange={handleChange}> <Option value="jack">Jack</Option> <Option value=& ...

Scenario-specific blueprints

I'm currently facing a challenge in incorporating logic into a dustjs template, and I find it challenging to integrate all the components seamlessly. Here is an example of the JSON data I have: { "names": [{ "name": "User 1", "is ...

What is the correct way to add a period to the end of a formatted text?

Hello, this marks the beginning of my inquiry. I apologize if it comes across as trivial but I have come across this piece of code: function format(input){ var num = input.value.replace(/\./g,''); if(!isNaN(num)){ num = num.toString ...

Error: TypeScript Knockout table failing to display data

I have a table that displays invoices, along with a nested table showing the individual checks associated with each invoice. I am using knockout and typescript to render these tables. Currently, I can successfully display the invoices but am facing difficu ...

How to enable Autocomplete popper to expand beyond the menu boundaries in Material UI

Within my Menu component, I have an Autocomplete element. When the Autocomplete is clicked, the dropdown list/Popper appears but it's confined within the Menu parent. How can I make it so that the Autocomplete's dropdown list/Popper isn't re ...

React UseEffect - Triggering only when data has been updated

In my current situation, I am facing a dilemma with the useEffect hook. I need it to not run on the initial render, but only when specific data is rendered, such as home.matchsPlayed and home.winHome. This is what my code looks like: useEffect(() => ...

initialize input data in vue

How can I set a default value for an input in a date picker using Vue JS? I have tried setting the data but it's not showing up. When I inspect the element, I see this code: https://i.stack.imgur.com/fQDLL.png Here is my script: new Vue({ e ...

Error occurs in Windows script while running a project installed globally

Upon installing my project globally, I encountered a Windows Script Host error. https://i.stack.imgur.com/unFVu.png What steps can I take to resolve this issue? The following is my JavaScript code snippet: Object.defineProperty(exports, "__esModule ...

Transferring information to React (Native) hooks in a way similar to how it is done

Transitioning to Hooks in React Native has been a new learning curve for me, especially when it comes to passing data to child elements. In the past with class-based components, passing props was as simple as using XML-style syntax. A Simple Example using ...

Default value for the href property in NextJS Link is provided

Is there a default href value for Next/Link that can be used, similar to the way it is done in plain HTML like this: <a href='#' ></a> I attempted to do this with Link, but it resulted in the page reloading. Leaving it empty caused a ...

Save the retrieved data in a variable and pass the entire JSON object as a prop to a React component

Having some trouble with my code. I need the app to fetch a JSON from an API and pass it as a prop so that each component file can use it and display the element on the screen. The issue is, I can't seem to figure out how to store the fetched informa ...

Retrieving the $index value for the chosen option in Angular

Consider this scenario: <input ng-model="selectedColor" type="text"></input> This approach will not produce the desired outcome: <p ng-click="changeColor($index)">change color</p> Is there another way to access $index without u ...

Utilize the sortable script for dynamically loaded items via AJAX

For the drag and drop feature on my website, I am using jQuery sortable. I have a button that displays results with items on the screen. These items can be dragged and dropped into various sections. The issue I'm facing is that if I include the sort ...

Convert HTML code into a customized JSON structure

Is there a way to convert HTML into a specific JSON object? For instance This HTML page is well-structured (originally in markdown). I am interested in creating a JSON version of the different sections present on the page. In this scenario, every "h2" s ...

Using ng-pattern to validate that a text field does not conclude with a particular term

In this code snippet, I am attempting to prevent a textfield from ending with any of the specified letters in the $scope.pointPattern variable. $scope.pointPattern = /^(?!.*ess|ence|sports|riding?$)/; $scope.error = "not valid"; Upon executio ...

Setting attributes on dynamically appended elements using Jquery

Whenever a user clicks on another user's name, a popup will appear with a form to send a message to that specific user. The goal is to dynamically change the 'action' attribute to include the user's ID in the form submission URL. Althou ...

How can I pull all data from an array using MongoDB query?

I have multiple arrays, but I am only interested in extracting the content related to "PIZZAS." Can anyone advise me on the appropriate query to achieve this? https://i.stack.imgur.com/wHolE.png ...

Transferring UTM parameters to a different page via a button click

Is there a way to extract parameters from a URL after the "?" and add them to a button's href in order to redirect to another landing page? I want to transfer UTM parameters to another page using JavaScript within the button. Original Homepage: Dest ...

Creating a custom function in a Node.js application and rendering its output in the front-end interface

I've been trying to scrape data from a website and display it using innerHTML, but I'm running into some issues. The code snippet I'm using is: document.getElementById('results').innerHTML = searchJobs(''); However, I ke ...