How can I filter an array of objects based on the value of a field and the remap the objects?

StackOverflow https://stackoverflow.com//questions/24052834

  •  21-12-2019
  •  | 
  •  

Question

I have the following object:

options.getOrderBy = function (type) {
    var OrderBy = [
        { type: 'x', id: 0, label: 'xx1', key: 'yy1' },
        { type: 'x', id: 1, label: 'xx2', key: [1,2] },
        { type: 'x', id: 9, label: 'xx2', key: ['a','b'] },
        { type: 'y', id: 0, label: 'xx44', key: 'yya' },
        { type: 'y', id: 1, label: 'xx45', key: 'yyb' },
        { type: 'y', id: 2, label: 'xx46', key: 'yyc' },
    ];
    return OrderBy;
};

What I need is that when the function is called with a type of ('x') then I want it to return something like:

[
   { id: 0, label: 'xx1', key: [1.2] },
   { id: 1, label: 'xx2', key: 'yy2' },
   { id: 9, label: 'xx2', key: ['a','b'] }
]

Can someone explain to me how I can filter an array based on the value of the type field and then just return an array of objects containing id, label and key?

Note that I have _lodash and I would like to use that if it makes it easier. Also my solution would be for browsers greater than IE9

Was it helpful?

Solution

My solution exploits Lodash's map and omit functions. See it here

var filter = function(collection, filterKey) {
    return _.map(collection, function(elem) {
        return _.omit(elem, filterKey);
    })        
}

Use it as:

var filtered = filter(OrderBy, 'type');

EDIT: taking into consideration also the value for filterKey

var filter = function(collection, filterKey, filterValue) {
                 return _.compact(_.map(collection, function(elem) {
                     if(elem[filterKey] === filterValue)
                         return _.omit(elem, filterKey);
                 }))        
              }

Use it as:

var filtered = filter(OrderBy, 'type', 'x');

SECOND EDIT: clearer version

var filterV2 = function(collection, filter) {
    return _(collection)
           .map(function (elem) { if(elem[filter.key] == filter.value) return _.omit(elem, filter.key) })
           .compact()
           .value()
} 

Use it as:

var filtered = filterV2(OrderBy, { key: 'type', value: 'x' });

OTHER TIPS

options.getOrderBy = function (type) {
    var OrderBy = [
        { type: 'x', id: 0, label: 'xx1', key: 'yy1' },
        { type: 'x', id: 1, label: 'xx2', key: 'yy2' },
        { type: 'y', id: 0, label: 'xx44', key: 'yya' },
        { type: 'y', id: 1, label: 'xx45', key: 'yyb' },
        { type: 'y', id: 2, label: 'xx46', key: 'yyc' },
    ];
    return OrderBy.filter(function(e) {
        return e.type === type;
    }).map(function(e) {
        delete e.type;
        return e;
    });
};

If you could change the OrderBy structure to an object, it will be much simpler:

options.getOrderBy = function (type) {
    var OrderBy = {
      x:[ 
          { id: 0, label: 'xx1', key: 'yy1' },
          {  id: 1, label: 'xx2', key: 'yy2' }
        ],
      y:[
          { id: 0, label: 'xx44', key: 'yya' },
          { id: 1, label: 'xx45', key: 'yyb' },
          { id: 2, label: 'xx46', key: 'yyc' }
        ]
    };
    return OrderBy[type];
};

You can filter the order options like this:

var newOrderBy = [];
for(var i = 0, l = OrderBy.length; i < l; i++) {
  if(OrderBy[i].type == type) {
    newOrderBy.push({
      id: OrderBy[i].id,
      label: OrderBy[i].label,
      key: OrderBy[i].key
    });
  }
}

Using underscore.js _.filter():-

options.getOrderBy = function (type) {
var OrderBy = [
    { type: 'x', id: 0, label: 'xx1', key: 'yy1' },
    { type: 'x', id: 1, label: 'xx2', key: [1,2] },
    { type: 'x', id: 9, label: 'xx2', key: ['a','b'] },
    { type: 'y', id: 0, label: 'xx44', key: 'yya' },
    { type: 'y', id: 1, label: 'xx45', key: 'yyb' },
    { type: 'y', id: 2, label: 'xx46', key: 'yyc' },
];
var filteredOrderBy = _.filter(OrderBy, function (order) {
    if (order.type === type) {
        return true;
    } else return false;
});
return filteredOrderBy ;

};

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top