What is the best method for iterating through an array and generating a glossary list organized by categories?

I have an array filled with definitions. How can I use Vue.js to iterate through this array and create a glossary list organized by letters?

Desired Output:

A

  • Aterm: A definition of aterm

B

  • Bterm: A definition of bterm

C

  • Cterm: A definition of cterm
  • Cterm: A definition of cterm
  • Cterm: A definition of cterm

Y

  • Yterm: A definition of yterm
  • Yterm: A definition of yterm

Z

  • Zterm: A definition of zterm
<div id="app" class="container">
  <div v-for="(item, index) in fields" :key="index">
    <span>{{ item.Term.charAt(0) }}
    <h3>{{ item.Term }}</h3>
    <p>{{ item.Definition }}</p>
  </div>
</div>

<script>
var app = new Vue({
  el: '#app',
  data: {
    parentMessage: 'Parent',
    fields: [
      { Term: 'Aterm', Definition: 'A definition for aterm' },
      { Term: 'Bterm', Definition: 'A definition for bterm' },
      { Term: 'Cterm', Definition: 'A definition for cterm' },
      { Term: 'Cterm', Definition: 'A definition for cterm' },
      { Term: 'Cterm', Definition: 'A definition for cterm' },
      { Term: 'Mterm', Definition: 'A definition for mterm' },
      { Term: 'Yterm', Definition: 'A definition for yterm' },
      { Term: 'Yterm', Definition: 'A definition for yterm' },
      { Term: 'Zterm', Definition: 'A definition for zterm' }
    ]
  },
  methods: {
    // do something
  }
})
</script>

Answer №1

Create a computed property that organizes the fields alphabetically by letter (using Array.prototype.reduce() on this.fields[]):

new Vue({
  computed: {
    fieldsByLetter() {
      const groups = this.fields.reduce((previous, current) => {
        const letter = current.Term.charAt(0).toUpperCase(); // using uppercase first letter
        previous[letter] ??= []; // create an array for this letter if it doesn't exist
        previous[letter].push(current); // add current field to the array
        return previous; // return updated object
      }, {});

      // sort fields by Term alphabetically
      Object.values(groups).forEach(fields => fields.sort((a, b) => a.Term.localeCompare(b.Term)));

      return groups;
    }
  },
})

Next, loop through the computed object with v-for, display the fields[] of the object using its own v-for, and each item in a <li> element to achieve the desired output:

<div id="app" class="container">
  <div v-for="(fields, letter) in fieldsByLetter" :key="letter">
    <h3>{{ letter }}</h3>
    <ul>
      <li v-for="item in fields" :key="item.Term">
        <span>{{ item.Term }}:</span>
        <span>{{ item.Definition }}</span>
      </li>
    </ul>
  </div>
</div>

demo

Answer №2

This solution takes a direct approach by harnessing the capabilities of lodash to tackle the issue effectively.

To get started, make sure to import the lodash library at the beginning of your script; this tool is well-known for its data manipulation functionalities.

import * as _ from "https://cdn.skypack.dev/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4824272c293b20087c66797f">[email protected]</a>";

Then, insert the following code snippet:

methods: {
    sorting(item) {
      return _.mapValues(
        _.groupBy(item, function (e) {
          return e.Term;
        })
      );
    },
  },
computed: {
    terms() {
      return this.sorting(this.fields);
    },
}

In this section, I've created a computed variable that manipulates the fields variable using the sorting function from lodash. The values are mapped and grouped based on the Term field within the array.

Lastly, ensure to adjust the structure of the HTML code accordingly:

<div id="app" class="container">
  <div v-for="(term, key, index) in terms" :key="index"> 
   <h4>{{ key.charAt(0) }}</h4> 
   <ul> 
     <li v-for="item in fields" :key="item.Term">
       <span>{{ item.Term }}:</span>
       <span>{{ item.Definition }}</span>
     </li&rt;
   </ul&rt;
>;
</div>;

For additional reference, you can view the Codepen demo here: https://codepen.io/auliaamir/pen/GROVJvr

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

What sets v-html apart from v-text?

I recently encountered this issue with the v-text directive: <h1 v-text="content.title"></h1> Result was: Brand Name is B&amp;C To resolve it, I switched to using the v-html directive in the line above: <h1 v-html="con ...

What is the proper way to define an element's style property in strict mode?

Assuming: const body = document.getElementsByTagName('body')[0]; const iframe = document.createElement('iframe'); iframe.src = protocol + settings.scriptUrl + a; iframe.height = 1; iframe.width = 1; iframe.scrolling = 'no'; ...

Access environmental variables within Next.js middleware

Within my nextjs project, I have declared variables in both the .env and next.conf.js files. The code snippet from the next.conf.js file looks like this: module.exports = { env: { NEXT_PUBLIC_JWT_SECRET: "...", }, publicRuntimeConfig: { ...

Dialog component from HeadlessUI doesn't support the Transition feature

Currently working with Next.JS version 14.1.3 I recently integrated the <Dialog> component from HeadlessUI and configured TailwindCSS. However, I encountered an issue where the Modal window doesn't have any transition effects even though I foll ...

The Execution of a Function Fails When Passed to a Functional Component

My functional component accepts a function called addEvent, which expects an event parameter. The problem arises when I try to call this function from props within another functional component, as the function does not seem to execute: const onOk = () =&g ...

Having trouble converting data back to JSON format after using JSON.parse in an ejs file with node and express

I'm retrieving data from an external API on my server, then attempting to pass that data to an ejs file using JSON.stringify(data), and trying to read the data in the ejs file by parsing it with JSON.parse(data). However, I am encountering issues wher ...

I am unable to access the specified file through the direct URL on the VueJS app with Vue Router that is hosted on Ampl

Today, I encountered a persistent issue with my VueJS app hosted on amplify. Everything is running smoothly, except for one thing. I need to provide direct access to a file (specifically to register an Apple merchant ID with stripe). I attempted to creat ...

"Node.js is throwing a 'postgres: relation does not exist' error even though the table it's referring to

After executing a psql command to create table users, I encountered some issues. CREATE TABLE users ( id integer NOT NULL, username text ); Although I can retrieve rows with SELECT * FROM users; When using node.js and the pg module for making c ...

Encountering the "TypeError: Unable to access property 'indexOf' of undefined" error while utilizing the ipfs-api

During my development work with the ipfs-api, I ran into an issue where adding an image file to the ipfs node was not functioning properly. Upon further investigation into the error details, it appears that the protocol is being treated as undefined in the ...

Organizing data in a database the arrangement way

I'm looking to populate an array with values for "name" and "nickname" extracted from an SQLITE database and then display them in an alert box. This task is part of a JavaScript project developed using Titanium Appcelerator. Below is the code snippe ...

VueJS throws an error when trying to access the 'settings' property of an undefined object

I'm encountering an issue with my basic input in a Vue component. The input should update data on change, but instead I'm getting the error message Uncaught TypeError: Cannot read property 'settings' of undefined Vue component <templ ...

How can I execute a basic query in jQuery or JavaScript based on a selected value that changes

After successfully retrieving the dropdown selection value with alert(selectedString) in this scenario, I am now looking to utilize that value for querying a table using mysqli and PHP. What is the best approach for querying a database table based on the ...

Showing a section of a DIV inside an iframe

I have implemented an HTML object in the following way: <object id="foo" name="foo" type="text/html" data="mypage.aspx"> </object> However, I do not want to display the entire content of mypage.aspx within the HTML object/iframe. In ...

Appending a JSON object to an array does not result in the object being added to the

Can anyone help me with an issue I'm facing? I have a code snippet where I am trying to push a JSON Object into an array, but the array is not updating properly. It only shows the last pushed element. var myData = {}; var id = 0; $("a").on('cli ...

A ReactJS Error occurred: {error: 400, reason: "Failed match", message: "Failed match [400]", errorType: "Meteor.Error"}

I encountered an issue while attempting to send form data to the server when clicking on the Next Button in a Wizard Form. The error that occurs is related to an "Undefined User" warning displayed in the Console during Step 1 of the form submission: " { ...

Tips for effectively passing generics to React Hooks useReducer

I am currently working with React Hooks useReducer in conjunction with Typescript. I am trying to figure out how to pass a type to the Reducer Function using generics. interface ActionTypes { FETCH, } interface TestPayload<T> { list: T[]; } inter ...

Res.end isn't halting the script's execution process

I'm currently facing an issue while building an API around a third-party API in my Express route. The problem is that the script keeps executing even after encountering a 406 error. Below is the snippet of my code: app.get('/submit/:imei', a ...

Design a personalized .OBJ / .MTL file and showcase it using the power of three.js

I attempted to create a basic blender model, export it to .obj/.mtl, and then render it with three.js. However, I am experiencing an issue. I have downloaded and uploaded the official three.js demo, and the objmtl-loader is functioning properly with the or ...

``After initialization, the service is unable to retrieve the object as

I have a special service that stores specific objects to be shared among different controllers. Here is an example of the code I am using: $rootScope.$on('controller.event', function(event, arg){ self.backendConnectorService.getBac ...

The output generated by grunt-contrib-handlebars differs from that of the handlebars npm task

Looking for some help with a problem similar to the one mentioned in this Stack Overflow question. Since that question hasn't been answered yet, I decided to create my own post. I'm currently attempting to precompile my handlebars template files ...