Mario
Mario

Reputation: 4998

How to reduce a literal object based on certain conditions?

I have the following task, having an array of objects with this structure

{
    fullName: 'Some Name',
    datashow: '1',
    classroom: 'C101',
    audio: true,
    cpu: false,
    internet: false,
    pointer: true,
    screen: false,
    description: 'Lorem ipsum dolor sit amet',
    blocks: '1,2'
}

And need to transform it into this:

{
    audio: true,
    pointer: true,
    description: 'Lorem ipsum dolor sit amet'
}

Following these conditions:

  1. The keys and values for fullName, datashow, classroom and blocks should not appear
  2. The remaining keys and values must appear only if its value is true

Right now i am using this solution currently works this way but I would like a faster and more elegant solution:

function reduceActivity(activity) {
    const newObject = {};

    for (key in activity) {
        if (key !== 'fullName' && key !== 'datashow' && key !== 'blocks' ) {
            if (activity[key]) {
                newObject[key] = activity[key];
            }
        }
    }

    return newObject;
}

Thanks for any help or recommendation

Upvotes: 0

Views: 29

Answers (3)

sfy
sfy

Reputation: 3258

Too late........

var fields =['classroom', 'audio', 'cpu', 'internet','pointer','screen','description']
var arr = [
    {
        fullName: 'Some Name',
        datashow: '1',
        classroom: 'C101',
        audio: true,
        cpu: false,
        internet: false,
        pointer: true,
        screen: false,
        description: 'Lorem ipsum dolor sit amet',
        blocks: '1,2'
    },
    {
        fullName: 'Some Name',
        datashow: '1',
        classroom: 'C101',
        audio: true,
        cpu: false,
        internet: false,
        pointer: true,
        screen: false,
        description: 'Lorem ipsum dolor sit amet',
        blocks: '1,2'
    },
        {
        fullName: 'Some Name',
        datashow: '1',
        classroom: false,
        audio: false,
        cpu: false,
        internet: false,
        pointer: false,
        screen: false,
        description: false,
        blocks: '1,2'
    }
    ]
    
var ret = arr.reduce((acc, obj)=>{

  var o={}
  fields.forEach(f => {
    if (obj[f] === true || obj[f].length > 0 || obj[f] === 0) o[f]=obj[f]
   })

   if(Object.keys(o).length === 0) 
    return acc
   else
    acc.push(o)
   return acc
},[])
console.log(ret)

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386756

You could take an object for the check if a key should be ignored. Then check it ans well as the check for the proerties value and return early.

function reduceActivity(activity) {
    var ignoreKeys = { fullName: true, classroom: true, datashow: true, blocks: true },
        newObject = {};

    Object.keys(activity).forEach(function (key) {
        if (ignoreKeys[key] || !activity[key]) {
            return;
        }
        newObject[key] = activity[key];
    });
    return newObject;
}

Upvotes: 1

Suren Srapyan
Suren Srapyan

Reputation: 68675

Try this solution. About performance there is no actual changes, you don't need to worry about that in this case, but in this solution you are giving the keys which must be excluded into the array and use the array to check the keys.

const obj = {
    fullName: 'Some Name',
    datashow: '1',
    classroom: 'C101',
    audio: true,
    cpu: false,
    internet: false,
    pointer: true,
    screen: false,
    description: 'Lorem ipsum dolor sit amet',
    blocks: '1,2'
};

const excludeKeys = ['fullName', 'datashow', 'blocks', 'classroom'];

const mappedObj = Object.keys(obj).reduce((o, item) => {

  if( !excludeKeys.includes(item) && obj[item]) {
      o[item] = obj[item];
  }
  
  return o;

}, {});

console.log(mappedObj);

With your solution in this code

for(key in activity)

you may have some logic issues if your object will have an prototype with it's properties. That key in activity will also give you prototypes properties which are enumerable.

Upvotes: 2

Related Questions