Tim Molloy
Tim Molloy

Reputation: 155

Manipulate Array of Objects in Javascript

I am not quite sure how to articulate what I'm trying to do in the title of this post, so please forgive me if the title is misleading or too ambiguous.

I have an array of objects I have created from an oData call (this is in an SAPUI5 application). The actual objects have more than three key/value pairs, but I stripped those out to keep this example simple.

[{
  "note_type_description": "General",
  "note_date": "/Date(872850505000)/",
  "note_text": "THIS IS A SUBSIDUARY OF THAT."
}, 
{
  "note_type_description": "General",
  "note_date": "/Date(873072000000)/",
  "note_text": "Say What Now?"
}, 
{
  "note_type_description": "General",
  "note_date": "/Date(891388800000)/",
  "note_text": "Say Who Now?"
},
{
  "note_type_description": "General",
  "note_date": "/Date(891993600000)/",
  "note_text": "Say When Now?"
},
{
  "note_type_description": "Interaction",
  "note_date": "/Date(909014400000)/",
  "note_text": "Say How Now?"
},
{
  "note_type_description": "Interaction",
  "note_date": "/Date(906422400000)/",
  "note_text": "Say Valentine Now?"
},
{
  "note_type_description": "Interaction",
  "note_date": "/Date(1485907200000)/",
  "note_text": "The latest interaction."
},
{
  "note_type_description": "Company Information",
  "note_date": "/Date(1477958400000)/",
  "note_text": "Some information about Person"
},
{
  "note_type_description": "Company Information",
  "note_date": "/Date(1483228800000)/",
  "note_text": "Are they private or public?"
},
{
  "note_type_description": "Company Information",
  "note_date": "/Date(1485907200000)/",
  "note_text": "Hope this is enough information!"
},
{
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1485993600000)/",
  "note_text": "Good!"
},
{
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1487116800000)/",
  "note_text": "Better!"
},
{
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1488412800000)/",
  "note_text": "Best!"
},
{
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1490918400000)/",
  "note_text": "Superb!"
}]

I want to iterate through the objects, and create a new array of objects containing two of each type (note_type_description) of the most recent entries (note_date) so I can render that in the UI.

I am somewhat new to JS, so I am mostly just unclear as to what array methods I would use to accomplish this. I am thinking this would start with Array.map() and go from there. Any assistance would be appreciated! I will keep plugging away at this and post any updates I have along the way!

** Update **

I used @Titus 's example, here is what it looks like after a bit of modification (switched from arrow functions to regular functions):

var oArr = [{
  "note_type_description": "General",
  "note_date": "/Date(872850505000)/",
  "note_text": "THIS IS A SUBSIDUARY OF THAT."
}, {
  "note_type_description": "General",
  "note_date": "/Date(873072000000)/",
  "note_text": "Say What Now?"
}, {
  "note_type_description": "General",
  "note_date": "/Date(891388800000)/",
  "note_text": "Say Who Now?"
}, {
  "note_type_description": "General",
  "note_date": "/Date(891993600000)/",
  "note_text": "Say When Now?"
}, {
  "note_type_description": "Interaction",
  "note_date": "/Date(909014400000)/",
  "note_text": "Say How Now?"
}, {
  "note_type_description": "Interaction",
  "note_date": "/Date(906422400000)/",
  "note_text": "Say Valentine Now?"
}, {
  "note_type_description": "Interaction",
  "note_date": "/Date(1485907200000)/",
  "note_text": "The latest interaction."
}, {
  "note_type_description": "Company Information",
  "note_date": "/Date(1477958400000)/",
  "note_text": "Some information about Person"
}, {
  "note_type_description": "Company Information",
  "note_date": "/Date(1483228800000)/",
  "note_text": "Are they private or public?"
}, {
  "note_type_description": "Company Information",
  "note_date": "/Date(1485907200000)/",
  "note_text": "Hope this is enough information!"
}, {
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1485993600000)/",
  "note_text": "Good!"
}, {
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1487116800000)/",
  "note_text": "Better!"
}, {
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1488412800000)/",
  "note_text": "Best!"
}, {
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1490918400000)/",
  "note_text": "Superb!"
}];

var sortedArr = oArr.sort(function(a, b) {
  b.note_date.match(/\d+/)[0] - a.note_date.match(/\d+/)[0]
});
var toRender = [];

sortedArr.forEach(function(v) {
  if (toRender.filter(function(vv) {
      return v.note_type_description == vv.note_type_description
    }).length < 2) {
    toRender.push(v);
  }
});

toRender.forEach(function(oKey) {
  console.log(oKey.note_type_description + " | " + oKey.note_text);
});

***** Update # 2 *****

Just to complete this and give context, here is what I ended up with:

    _setNotes: function(oResponse) {
        if (typeof oResponse.results !== "undefined") {
            var aAllNotes = oResponse.results;
            var aTruncNotes = [];

            var sortedNotes = aAllNotes.sort(function(a, b) {
                a = new Date(a.note_date);
                b = new Date(b.note_date);
                return a>b ? -1 : a<b ? 1 : 0;
            });

            sortedNotes.forEach(function(v) {
                if (aTruncNotes.filter(function(vv) {
                        return v.note_type_description === vv.note_type_description;
                    }).length < 2) {
                    aTruncNotes.push(v);
                }
            });
        }
        this.getView().getModel("view").setProperty("/allNotes", aAllNotes);
        this.getView().getModel("view").setProperty("/truncNotes", aTruncNotes);
    }

Now I can call the 'truncNotes' object in my UI5 XML view and it is returned as so:

enter image description here

Upvotes: 0

Views: 6384

Answers (1)

Titus
Titus

Reputation: 22474

One way of doing this will be to first sort your array by note_date and then, create a new array and add to it only 2 objects with the same note_type_description value.

Here is an example:

var arr = [{
  "note_type_description": "General",
  "note_date": "/Date(872850505000)/",
  "note_text": "THIS IS A SUBSIDUARY OF THAT."
}, 
{
  "note_type_description": "General",
  "note_date": "/Date(873072000000)/",
  "note_text": "Say What Now?"
}, 
{
  "note_type_description": "General",
  "note_date": "/Date(891388800000)/",
  "note_text": "Say Who Now?"
},
{
  "note_type_description": "General",
  "note_date": "/Date(891993600000)/",
  "note_text": "Say When Now?"
},
{
  "note_type_description": "Interaction",
  "note_date": "/Date(909014400000)/",
  "note_text": "Say How Now?"
},
{
  "note_type_description": "Interaction",
  "note_date": "/Date(906422400000)/",
  "note_text": "Say Valentine Now?"
},
{
  "note_type_description": "Interaction",
  "note_date": "/Date(1485907200000)/",
  "note_text": "The latest interaction."
},
{
  "note_type_description": "Company Information",
  "note_date": "/Date(1477958400000)/",
  "note_text": "Some information about Person"
},
{
  "note_type_description": "Company Information",
  "note_date": "/Date(1483228800000)/",
  "note_text": "Are they private or public?"
},
{
  "note_type_description": "Company Information",
  "note_date": "/Date(1485907200000)/",
  "note_text": "Hope this is enough information!"
},
{
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1485993600000)/",
  "note_text": "Good!"
},
{
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1487116800000)/",
  "note_text": "Better!"
},
{
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1488412800000)/",
  "note_text": "Best!"
},
{
  "note_type_description": "Relationship Strategy",
  "note_date": "/Date(1490918400000)/",
  "note_text": "Superb!"
}];

var sortedArr = arr.sort((a, b) => b.note_date.match(/\d+/)[0] - a.note_date.match(/\d+/)[0]);
var toRender = [];

sortedArr.forEach(v => {
    if(toRender.filter(vv => v.note_type_description == vv.note_type_description).length < 2){
         toRender.push(v);
    }
});

console.log(toRender);

This is not the most efficient way of doing it but it will introduce you to the JavaScript array functions like sort, filter and forEach

Upvotes: 1

Related Questions