Leveraging Lodash to retrieve values based on specific keys, even when certain keys are missing

How can I efficiently utilize Lodash while iterating through an array to extract and assign relevant values?

I have an unfiltered array which contains ID and name[x].text elements. Some objects in the array may not have French text available, in which case I want to default to English text.

const response = {
    "data": {
      "Animals": [
        {
          "id": "1",
          "name": [
            {
              "language": "en-US",
              "text": "Horse"
            }
          ]
        },
        ...
      ]
    }
  }


console.log(response.data.Animals.map(animal => animal.name[0].text)); // Accesses only English text, but I need to handle cases where French text is present.

In order to achieve a more accurate result that includes both French and English text with some improvements, follow these steps:

  1. Retrieve values based on keys ("en-US" and "fr-CA") to ensure correct data selection.

  2. While populating a table using mapping, avoid creating a new array as it may lead to index loss if text is missing, defaulting to English text instead.

  3. For advanced usage of Lodash to set values (either in English or French), you can implement the following:

     arr.map((obj) => {
     const id = obj.id;
     const englishtext = _.get(obj, 'name[0].text', 'N/A');
     const frenchtext = _.get(obj, 'name[1].text', englishtext);
     return { id, englishtext, frenchtext };
    

    }

UPDATE: I apologize for any confusion caused by my initial question. To clarify, I seek an expected output resembling the following format when mapping the 'response' variable:

EXPECTED OUTPUT:

[
{
id: 1,
engname: Horse,
frenchname: Horse (fallback to English),
},
...
{
id:3,
engname:Cat,
frenchname: Un Chat, (French option available)
}
...
and so forth.. 
] 

Answer №1

In this case, I would provide a solution without using Lodash as it is not essential here. However, if you specifically require a Lodash solution, feel free to disregard my non-Lodash approach.

Based on my understanding of your question, the extraction rule set you wish to implement is as follows:

  1. If there is French text available, prioritize that over English text. Additionally, French text always follows English text in the array (-1 index represents French text).

  2. If French text is absent, default to using the English text (English text is guaranteed for all items).

In such a scenario, options like Array.prototype.pop() or Array.prototype.at() could be utilized to achieve your goal.

Solution using Array.prototype.pop()

response.data.Animals.map(animal => animal.name.pop().text)

Pros:

  • Supported across modern browsers.

Cons:

  • Mutates original data and alters array length.

Solution using Array.prototype.at()

response.data.Animals.map(animal => animal.name.at(-1).text)

Pros:

  • Immutable operation, preserving original data.

Cons:

  • Potential lack of support in certain browsers.

If open to non-Lodash solutions, consider implementing one of these alternatives.

Update

Appreciation to @WildThing for revising the query. You can utilize the following code snippet for the desired mapping:

response.data.Animals.map(animal => {
  engName = animal.name.find(name => name.language === "en-US");
  frenchNameIfExists = animal.name.find(name => name.language === "fr-CA");

  return {
    id: animal.id,
    engname: engName.text,
    frenchname: (frenchNameIfExists || engName).text,
  }
})

Answer №2

Maybe you can achieve this without using lodash:

const convertToMyArray = (array, languageCode = "en-US", secondaryLanguageCode = "fr-CA") => {
  return array.map(({ id, name }) => {
    const primaryName = name
      .find(({ language }) => language === languageCode)
      .text;
    const secondaryName =  name
      .find(({ language }) => language === secondaryLanguageCode)
      ?.text;
      
    return { id, primaryName, secondaryName: secondaryName ?? primaryName }
  });
};

console.log(convertToMyArray(response.data.Animals));

// [
//   {id: '1', primaryName: 'Horse', secondaryName: 'Horse'},
//   {id: '2', primaryName: 'Pig', secondaryName: 'Pig'},
//   {id: '3', primaryName: 'Cat', secondaryName: 'Un Chat'},
//   {id: '4', primaryName: 'Dog', secondaryName: 'Un Chien'},
// ]

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

Updating component (`App`) during the rendering of another component is not allowed

I have encountered an issue with a react component that I am struggling to resolve. It involves a radial knob control, similar to a slider, and I am trying to achieve two main objectives: Adjust the knob and pass its value up to the parent component for ...

Manipulating a textarea in jQuery by inserting a string and selecting a specific portion of it

Just as seen on SO with the B button: **bold text** Including that bold text is automatically highlighted and the cursor is placed right before the b ...

Exploring various components within a JavaScript array

I keep a list of names in a file named Ignore.json [ "George", "Carl" ] The filename is ignore.json Within my program, I load the contents of the file into a variable called ignore var ignore; ignore = require("./Ignore.json"); Now, I need to check i ...

What is the best way to update a value and trigger a re-render in ReactJS?

this.state={ value: 'v1', newValue: '', } componentDidMount = () => { let nV = this.state.value + 'received'; this.setState({ newValue: nV, }); } tabClick = (val) => { this.setState({ value: val, ...

Three JS tutorial: Slicing a 3D shape with a vertical plane

Can Three JS achieve the functionality of slicing a mesh or object with a plane (specifically along the Y axis) that is movable? I am looking to replicate the capability shown in this image: The objective is to maintain the integrity of the mesh so that u ...

Transforming a transmitted statement

Is it possible to get the following broadcasted expression working? J = rand(4,4) fx1 = rand(2,2) fx2 = rand(2,2) @. J[:,1] = fx1 + fx2 I am really interested in achieving something like: @. J[:,1] = vec(fx1 + fx2) The idea is to reshape it without all ...

jquery technique for toggling a single button

My goal is to use jQuery to toggle a button rather than the typical paragraph toggling. I want the button to appear and disappear when clicked, while also increasing the "score" upon each click and decreasing it when the button reappears. Can anyone guide ...

Ways to create a sequential appearance of elements through CSS animations

Can you help me achieve a wave effect for elements appearing one by one using CSS animation (jQuery)? Currently, all the elements show up at once and I want to create a wave-like motion. Any assistance would be greatly appreciated. $(window ...

The absence of the function crypto.createPrivateKey is causing issues in a next.js application

For my next.js application, I am utilizing the createPrivateKey function from the crypto module in node.js. However, I encountered an issue as discussed in this thread: TypeError: crypto.createPrivateKey is not a function. It seems that this function was a ...

I am experiencing an issue where my Laravel website does not refresh automatically

Having trouble with the URL (url: "/ultimo-pedidox"). It seems to be loading correctly, but the view isn't refreshing as expected. @extends('store/template') @section('content') <div style="margin-top: 55px;" ...

Inspecting the Ace Editor within the onbeforeunload event handler to confirm any modifications

I'm attempting to utilize the $(window).on('beforeunload', function(){}); and editor.session.getUndoManager().isClean(); functions within the ace editor to detect whether a user has made modifications to a document without clicking the submi ...

How can I use JavaScript to show a div upon clicking an input element?

I am looking to make a block div visible when an input field is clicked. <input class="indifferent" type="radio" name="decision" value="indifferent"> Indifferent </br> <div class="input" style="display: none;"> Please assist with our com ...

Why does appending to a TextArea field fail in one scenario but succeed in another when using Javascript?

There is a JavaScript function that captures the value from a select dropdown and appends it to the end of a textarea field (mask) whenever a new selection is made. function addToEditMask(select, mask) { var selectedValue = document.getElementById(sel ...

JS script for clicking various icons on a webpage that trigger the opening of new tabs

I am working on a webpage where I have 9 icons with the same class. I am trying to write JavaScript code that will automatically open all 9 icons when the webpage loads. I tried using the code below, but it only clicks on the first icon and stops. let ...

Arrange the colors in a predetermined sequence within the array

I am looking to implement a loop through an array and assign specific colors to each array element based on a predetermined order. Elements at positions first, fifth, ninth, and so on should be colored in red. Elements at positions second, sixth, tenth, a ...

The error message keeps appearing consistently. What is the best way to manage this error?

Even after entering the data in this field, it was supposed to disappear. However, that didn't happen as expected. <md-input-container class="md-block" flex-gt-sm> <label>Budget</label> <input name="budget" ng-model="newTri ...

React failing to display changes in child components even after using setState

When I delete an "infraction" on the child component, I try to update the state in the parent component. However, the changes do not reflect visually in the child component even though the state is updated. It seems like it's related to shallow update ...

Incorporating intricate HTML elements through a Chrome content script

Currently, I am utilizing Chrome extension's content script to generate a sophisticated display that is incorporated into web pages. Initially, I tested it by integrating it directly onto a website, but now I want to package it in an extension. The ...

Creating a variable in JavaScript

In my HTML body, I have set up a global variable named index with the value <%var index = 0;%>. This allows me to access it throughout the code. I'm trying to assign the value of $(this).val() to <% index %>, but I can't seem to get ...

Ensuring the validity of input tags

I encountered an issue with an input tag that has a specific logic: https://codepen.io/ion-ciorba/pen/MWVWpmR In this case, I have a minimum value retrieved from the database (400), and while the logic is sound, the user experience with the component lea ...