When the same field element is transformed into an array of values

I am attempting to create a mapped array with keys similar to the structure below

const data =    [{
          "_id": "5f0ffb96d67d70c1a3b143e7",
          "name": "USER",
          "type": "CUSTOM",
          "origin": "USER",
          "conditions": [{
            "_id": "5f0ffb96d67d70c1a3b143e8",
            "field": "status",
            "value": "Nomita",
            "operator": "equal"
          }, {
            "_id": "5f0ffb96d67d70c1a3b143e9",
            "field": "current_status",
            "value": "ACTIVE",
            "operator": "equal"
          }, {
            "_id": "5f0ffb96d67d70c1a3b143ea",
            "field": "user_group_uuid",
            "value": "d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2",
            "operator": "equal"
          }, {
            "_id": "5f0ffb96d67d70c1a3b143eb",
            "field": "user_group_uuid",
            "value": "20348751-dcaa-4227-a0ff-912b27180aee",
            "operator": "equal"
          }]
        }]

The above code snippet shows the input.

const filters_data = { ...data[0] }
const filters_mapping = (array, keyField) =>
    array.reduce((obj, item) => {
            obj[item[keyField]] = item
            return obj
        }, {})
const filter_items = filters_mapping(filters_data.conditions,'field');

By executing this code, I am currently receiving the following output:

{ user_status:
   { _id: 5f0ffb96d67d70c1a3b143e8,
     field: 'status',
     value: 'Nomita',
     operator: 'equal' },
  current_status:
   { _id: 5f0ffb96d67d70c1a3b143e9,
     field: 'current_status',
     value: 'ACTIVE',
     operator: 'equal' },
  user_group_uuid:
   { _id: 5f0ffb96d67d70c1a3b143eb,
     field: 'user_group_uuid',
     value: 'd12s0a7c-11ac-7abf-bl03-f0b70e26f8f2',
     operator: 'equal' } }

However, what I truly desire is a result like this, where the value is an array when multiple values are available for a single field:

{ user_status:
       { _id: 5f0ffb96d67d70c1a3b143e8,
         field: 'status',
         value: ['Nomita'],
         operator: 'equal' },
      current_status:
       { _id: 5f0ffb96d67d70c1a3b143e9,
         field: 'current_status',
         value: ['ACTIVE'],
         operator: 'equal' },
      user_group_uuid:
       { _id: 5f0ffb96d67d70c1a3b143eb,
         field: 'user_group_uuid',
         value: ['d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2','20348751-dcaa-4227-a0ff-912b27180aee'],
         operator: 'equal' } }

This alteration should only occur when there are multiple fields present. Otherwise, a singular string should be returned as per usual.

Answer №1

Hello there, I have implemented your code but with a slight modification where I combine values with the same field value before reducing it. Here is a sample of how it works:

const data = [{
          "_id": "5f0ffb96d67d70c1a3b143e7",
          "name": "USER",
          "type": "CUSTOM",
          "origin": "USER",
          "conditions": [{
            "_id": "5f0ffb96d67d70c1a3b143e8",
            "field": "status",
            "value": "Nomita",
            "operator": "equal"
          }, {
            "_id": "5f0ffb96d67d70c1a3b143e9",
            "field": "current_status",
            "value": "ACTIVE",
            "operator": "equal"
          }, {
            "_id": "5f0ffb96d67d70c1a3b143ea",
            "field": "user_group_uuid",
            "value": "d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2",
            "operator": "equal"
          }, {
            "_id": "5f0ffb96d67d70c1a3b143eb",
            "field": "user_group_uuid",
            "value": "20348751-dcaa-4227-a0ff-912b27180aee",
            "operator": "equal"
          }]
        }]

const conditions_combined = _.uniqWith(data[0].conditions, function(a, b) {
  if (a.field === b.field) {
    b.value += ', ' + a.value;
    b.value = b.value.split(",");
    return true;
  }
});
data[0].conditions = conditions_combined;
const filters_data = { ...data[0] };
const filters_mapping = (array, keyField) =>
    array.reduce((obj, item) => {
            obj[item[keyField]] = item
            return obj
        }, {})
const filter_items = filters_mapping(filters_data.conditions,'field');
console.log(filter_items);
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="503c3f3431233810647e61677e6160">[email protected]</a>/lodash.min.js"></script>

Explanation: The implementation uses _.uniqWith from lodash to merge values with the same field value.

Answer №2

One possible solution is presented below.

Your code may not account for scenarios where the key already exists in the data structure.

const data = [{
  "_id": "5f0ffb96d67d70c1a3b143e7",
  "name": "USER",
  "type": "CUSTOM",
  "origin": "USER",
  "conditions": [{
    "_id": "5f0ffb96d67d70c1a3b143e8",
    "field": "status",
    "value": "Nomita",
    "operator": "equal"
  }, {
    "_id": "5f0ffb96d67d70c1a3b143e9",
    "field": "current_status",
    "value": "ACTIVE",
    "operator": "equal"
  }, {
    "_id": "5f0ffb96d67d70c1a3b143ea",
    "field": "user_group_uuid",
    "value": "d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2",
    "operator": "equal"
  }, {
    "_id": "5f0ffb96d67d70c1a3b143eb",
    "field": "user_group_uuid",
    "value": "20348751-dcaa-4227-a0ff-912b27180aee",
    "operator": "equal"
  }]
}];

const mutatedData = data[0].conditions.reduce((temp, {
  _id,
  field,
  value,
  operator,
}) => {
  // Check if the field already exists
  if (temp[field]) {
    temp[field].value = [
      ...(temp[field].value instanceof Array ?
        temp[field].value : [temp[field].value]),

      value,
    ];

    return temp;
  }

  // Handle case where field doesn't exist yet
  temp[field] = {
    _id,
    field,
    value,
    operator,
  };

  return temp;
}, {});


console.log(mutatedData);


Shortened version

const data = [{
  "_id": "5f0ffb96d67d70c1a3b143e7",
  "name": "USER",
  "type": "CUSTOM",
  "origin": "USER",
  "conditions": [{
    "_id": "5f0ffb96d67d70c1a3b143e8",
    "field": "status",
    "value": "Nomita",
    "operator": "equal"
  }, {
    "_id": "5f0ffb96d67d70c1a3b143e9",
    "field": "current_status",
    "value": "ACTIVE",
    "operator": "equal"
  }, {
    "_id": "5f0ffb96d67d70c1a3b143ea",
    "field": "user_group_uuid",
    "value": "d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2",
    "operator": "equal"
  }, {
    "_id": "5f0ffb96d67d70c1a3b143eb",
    "field": "user_group_uuid",
    "value": "20348751-dcaa-4227-a0ff-912b27180aee",
    "operator": "equal"
  }]
}];

const mutatedData = data[0].conditions.reduce((temp, {
  _id,
  field,
  value,
  operator,
}) => (temp[field] = temp[field] ? ((temp[field].value = [
  ...(temp[field].value instanceof Array ?
    temp[field].value : [temp[field].value]),

  value,
]) && temp[field]) : {
  _id,
  field,
  value,
  operator,
}) && temp, {});

console.log(mutatedData);

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

Pattern to find a particular, multi-line item within JSON array

Dealing with JSON lists can sometimes be tricky. Here is an example of what a JSON list might look like: [ { "accessType": "*", "principalType": "ROLE", "principalId": "$unauthenticated", "permission": "DENY" }, { ...

Obtaining a JSON file from Firebase Storage

Is it possible to retrieve a JSON file from Firebase Storage for use without needing to push it back? If so, how can I accomplish this using Angular with Firebase Storage? If not, would the Firebase database be a better option for this scenario? I have ...

What can be done to ensure that two separate react-native Picker components do not interfere with each other's

Encountering an issue with two Pickers in a react-native View. Whenever I select a value in one Picker, it causes the other Picker to revert back to its initial item in the list. It seems like the onValueChange function is being triggered for both Pickers ...

Embedding complex JSON information into an HTML dropdown menu

Here is a JSON string that I am working with: { "electronics": { "cameras": [ "sony", "nikon", "canon" ], "TV": "none", "laptop": [ "hp", "apple", "sony" ] }, "home": { "furniture": [ ...

What is the best way to implement multiple preload scripts for various Electron windows when utilizing electron forge with the webpack template?

I am utilizing the typescript+webpack template provided by electron forge. To load a single preload script with webpack, I need to set the constant called MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY in the package.json file. This constant can be configured like thi ...

What is the best way to iterate over an associative array and display the contents as a list?

After successfully setting up my initial array, I have been struggling to loop through each row and display the three columns/elements in a tag. Here is the var_dump of my array: array(27) { [3]=> array(3) { ["id"]=> string(3) "295" ["title"]=gt ...

Query multiple tables in SQL, performing multiple joins to include a column field that displays a list separated by commas

I currently have a query where I'm joining three distinct tables - node, control, and service. Here are the column headers and some sample data from each: NODE TABLE (over 7000 rows) nodeID | host | serviceID | controlID 1 | server1 ...

Getting the location of a mouse click and adding tags (marks) on an image: a simple guide

Is there a way to incorporate images with tagged marks similar to Facebook's image tagging feature? How can I retrieve the X and Y coordinates of tags on the image itself (not the screen) and display them in a responsive manner? ...

Unable to navigate a simulated scrollbar

As someone who is new to web development, I am embarking on the journey of building a UI Grid that can effectively display a large amount of data. My goal is to implement a scrollbar that allows for horizontal scrolling across approximately 1,000,000 data ...

Arrange the array in chronological order based on the month and year

I'm looking for assistance with sorting an array by month and year to display on a chart in the correct order. Array1: ['Mar19','Apr18','Jun18','Jul18','May18','Jan19'....]; Desired Output: ...

The frustrating error of ember-data duplicating records is causing quite a

Using ember-data#canary has revealed a serious bug in finding records from the store. File: router.js this.resource('games', function() { this.route('game', { path: '/:game' }); }); File: games_route.js App.GamesRoute ...

Implementing HTML content inside an el-select component in Vue.js using Element UI

I am working with a dropdown feature that has various options: var Main = { data() { return { drawer: { form: { period: null } }, data : [ { label: "JAN to MAR 2021", value: " ...

Adding an array to an object within an array using AngularJS

I'm struggling to comprehend how to insert an array into an object property. I've tried several approaches but I still can't seem to grasp it. What I'm aiming to achieve is to add a menu item to my menu and then include subitems. You ca ...

Issues with PHP not reflecting changes to MySQL database

I'm struggling to find a solution to the issue I'm facing on various forums. The problem involves two pages, an HTML page and a PHP page. The HTML page simply populates a dropdown list from a database column. Below is a simplified version of the ...

The JavaScript audio is not working for the first three clicks, but starts playing smoothly from the fourth click onwards. What could be causing this issue?

$(".btn").click(function(event){ playSound(event.target.id); }); function playSound(name){ $("." + name).click(function() { new Audio("sounds/" + name + ".mp3").play(); ...

tips for changing a json string into yaml format

I am facing an issue with the given code snippet: string stringXDoc = JsonConvert.SerializeObject(ConnectedItemOperations.GetConnectedItemById(id).Edits.EditableData); var json = JsonConvert.DeserializeObject(stringXDoc); The specific file is triggeri ...

Retrieve the element from the most recent append() function invocation

Is it possible to change the chain context to a new DOM node when using append() to insert it? Here is an example code snippet demonstrating this: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org ...

Challenges with removing and adding controllers in Angular versions 1.2 and above

I am currently in the process of migrating my app from Angular 1.2 to 1.3 and I am encountering an issue with the different behaviors of the removeControl and addControl functions. Within my directive, I have implemented a functionality that escapes regis ...

Discovering a specific element using jQuery

I am trying to work with a div structure like this: <div class="country"> <div class="cty_popover"> <p>TITLE</p> <ul> <li>NAME 1</li> <li>NAME 2</li> ...

Setting a Vue property on an object

I am currently working on a component that needs to append a property to an array. Here is the initial array structure: [ { date: "17/11/2020", dateTime: false, hour: "00", minute: "00", }, ...