Pankaj Mishra
Pankaj Mishra

Reputation: 13

Filter array by keys and by values

I have below objects of array and want to filter with key and values

var arrayObj = [{name:'ram',lastname:'jha',address:{fistLine:'100 ft raod',street:'kfc'},mobileNumber:12345745},
               {name:'rakesh',lastname:'jha',address:{fistLine:'200 ft raod',street:'pizza hut'},mobileNumber:12345746},
               {name:'pankaj',lastname:'jha',address:{fistLine:'300 ft raod',street:'abc line'},mobileNumber:12345747}];

I want output like below:

let newarrayObj:[['name','lastname', 'address.fistLine','address.street','mobileNumber'],
                 ['ram','jha','100 ft raod','kfc','12345745'],
                 ['rakesh','jha','200 ft raod','pizza hut','12345746'],
                 ['pankaj','jha','300 ft raod','abc line','12345747']]

Upvotes: 0

Views: 83

Answers (3)

Julien Dargelos
Julien Dargelos

Reputation: 395

Assuming arrayObj has at least 1 item, you could do the following, no matter how deep your objects are:

const flatKeys = object => Object.entries(object).reduce((keys, [key, value]) => {
  if (typeof value === 'object') { // && value !== null if needed
    flatKeys(value).forEach(subKey => keys.push(key + '.' + subKey))
  } else {
    keys.push(key)
  }

  return keys
}, [])

const flatValues = object => Object.values(object).reduce((values, value) => {
  if (typeof value === 'object') { // && value !== null if needed
    flatValues(value).forEach(subValue => values.push(subValue))
  } else {
    values.push(value)
  }

  return values
}, [])

const arrayObj = [
  { name: 'ram',    lastname:'jha', address: { fistLine:'100 ft raod', street: 'kfc'       }, mobileNumber: 12345745 },
  { name: 'rakesh', lastname:'jha', address: { fistLine:'200 ft raod', street: 'pizza hut' }, mobileNumber: 12345746 },
  { name: 'pankaj', lastname:'jha', address: { fistLine:'300 ft raod', street: 'abc line'  }, mobileNumber: 12345747 }
]

const newarrayObj = [flatKeys(arrayObj[0]), ...arrayObj.map(flatValues)]

console.log(newarrayObj)

Upvotes: 1

Dhananjai Pai
Dhananjai Pai

Reputation: 6005

The below solution works upto 2 levels deep. If it is deeper, you will have to use a recursive approach. The current soution checks if the value is an object to create the inner loop and then reduces the object to the required format

var arrayObj = [{name:'ram',lastname:'jha',address:{fistLine:'100 ft raod',street:'kfc'},mobileNumber:12345745},
               {name:'rakesh',lastname:'jha',address:{fistLine:'200 ft raod',street:'pizza hut'},mobileNumber:12345746},
               {name:'pankaj',lastname:'jha',address:{fistLine:'300 ft raod',street:'abc line'},mobileNumber:12345747}];


let newArrayObj = arrayObj.reduce((acc,obj,i) => {
  if(!acc[0]) acc[0]=[];
  acc[i+1]=[];
  Object.entries(obj).forEach(([key,value]) => {
    if(value && typeof value!= 'object' && !acc[0].includes(key)) {
       acc[0].push(key);
       acc[i+1].push(value);
    } else if (value && typeof value === 'object') {
       Object.entries(value).forEach(([k,v]) => {
         let val = key+'.'+k;
         if(!acc[0].includes(val)) acc[0].push(val);
         acc[i+1].push(v);
        });
    }
  });
  return acc;
},[]) 
                 
console.log(newArrayObj);

Upvotes: 0

Nikhil
Nikhil

Reputation: 6641

You can use map() with Object.keys(), Object.values(), and flat().

var arrayObj = [{ name: 'ram', lastname: 'jha', address: { firstLine: '100 ft raod', street: 'kfc' }, mobileNumber: 12345745 }, { name: 'rakesh', lastname: 'jha', address: { fistLine: '200 ft raod', street: 'pizza hut' }, mobileNumber: 12345746 }, { name: 'pankaj', lastname: 'jha', address: { fistLine: '300 ft raod', street: 'abc line' }, mobileNumber: 12345747 } ];

var keys = Object.entries(arrayObj[0]).map(([key, value]) => {
  if (typeof value === 'object') {
    return Object.keys(value).map(subKey => key + '.' + subKey);
  } else {
    return key;
  }
}).flat();

var values = arrayObj.map(item =>
  Object.values(item).map(value =>
    typeof value === 'object' ? Object.values(value) : value
  ).flat()
);

var result = [keys].concat(values);

console.log(result);

Upvotes: 0

Related Questions