最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Convert and filter array of objects to one object - Stack Overflow

programmeradmin8浏览0评论

I have next array of objects:

const fields = [
    { givenName: 'firstName' },
    { familyName: 'lastName' },
    { 'custom:data': 'blabla' },
    { 'custom:data2': '' },
    { 'custom:data3': null },
  ];

What I need is to filter out elements which is empty, null or undefined and convert it to one object pameters:

{  
   givenName: 'firstName',
   familyName: 'lastName',
   'custom:data': 'blabla'
}

I have next array of objects:

const fields = [
    { givenName: 'firstName' },
    { familyName: 'lastName' },
    { 'custom:data': 'blabla' },
    { 'custom:data2': '' },
    { 'custom:data3': null },
  ];

What I need is to filter out elements which is empty, null or undefined and convert it to one object pameters:

{  
   givenName: 'firstName',
   familyName: 'lastName',
   'custom:data': 'blabla'
}
Share Improve this question asked Jan 15, 2021 at 14:09 TedTed 1,7604 gold badges31 silver badges54 bronze badges 3
  • May the objects have more than one keys? – FZs Commented Jan 15, 2021 at 14:16
  • 1 nope, only one. – Ted Commented Jan 15, 2021 at 14:18
  • 2 You have explicitly said to exclude null, undefined and '' (empty) meaning you want to keep everything else. Most answers including the one you have accepted don't do that. Most rely on truthy/falsy checks excluding values such as 0, false and NaN. (FYI) – custommander Commented Jan 15, 2021 at 15:06
Add a ment  | 

8 Answers 8

Reset to default 6

You could filter the array by looking to the values. This approach assumes, that only one key/value pair is available.

const
    fields = [{ givenName: 'firstName' }, { familyName: 'lastName' }, { 'custom:data': 'blabla' }, { 'custom:data2': '' }, { 'custom:data3': null }],
    result = Object.assign({}, ...fields.filter(o => {
        const [v] = Object.values(o);
        return v || v === 0 || v === false;
    }));

console.log(result);

How to check whether a value is empty?

Most people would go about this with a truthy check:

const empty = x => x ? false : true;

empty(null);      //=> true
empty(undefined); //=> true
empty('');        //=> true

But that's always going to exclude things you perhaps didn't intend to exclude:

empty(0);         //=> true
empty(false);     //=> true
empty(NaN);       //=> true

Admittedly NaN could be seen as the "empty" value of its type but for the sake of your question and educational purpose we'll say it's not.

The "workaround" is often something like that:

const empty = x => (x || x === 0 || x === false || Number.isNaN(x)) ? false : true;

However this doesn't need to be more plicated than this:

const empty = x => x == null || x === '' ? true : false;

Checking for either undefined or null is one example where not using triple equality makes sense:

null == undefined;
// true
null === undefined;
// false

See Google JavaScript Style Guide.

If you need to exclude null, undefined and '' please don't rely on clever shorthand tricks and just be explicit about it. Type checking should be a straightforward job (YMMV) and not a show-off contest. Future you and your team mates will thank you.

As for your question, I'd suggest this:

Merge everything you've got with Object.assign:

Object.assign({}, {a:1}, {b:2}, {c:2});
// {a: 1, b: 2, c: 3}

Then deconstruct it into pairs, exclude those whose value is empty, then reconstruct the object from what's left:

const merge = xs =>
  Object.fromEntries(
    Object.entries(
      Object.assign({}, ...xs))
        .filter(([_, v]) =>
          v != null && v !== ''));
        
        
console.log(merge(fields));
<script>
const fields = [
  { givenName: 'firstName' },
  { familyName: 'lastName' },
  { 'custom:data': 'blabla' },
  { 'custom:data2': '' },
  { 'custom:data3': null },
];
</script>

const fields = [
    { givenName: 'firstName' },
    { familyName: 'lastName' },
    { 'custom:data': 'blabla' },
    { 'custom:data2': '' },
    { 'custom:data3': null },
  ];
  
 res = fields.reduce((acc, cur) => {
    if (cur[Object.keys(cur)[0]]) {
       acc = { ...acc, ...cur }
    }
    return acc
 }, {})
 
 console.log(res)

const fields = [
  { givenName: 'firstName' },
  { familyName: 'lastName' },
  { 'custom:data': 'blabla' },
  { 'custom:data2': '' },
  { 'custom:data3': null },
];

const result = fields.reduce( ( acc, field ) => {
  Object.keys( field ).forEach( ( key ) => {
    if( field[key] ) {
      acc[key] = field[key];
    }
  } )
  return acc;
}, {} )
    
console.log(result)

You could use reduce and forEach and check if value of each property is falsy or not.

const fields = [
  { givenName: 'firstName' },
  { familyName: 'lastName' },
  { 'custom:data': 'blabla' },
  { 'custom:data2': '' },
  { 'custom:data3': null },
];

const result = fields.reduce((r, e) => {
  Object.entries(e).forEach(([k, v]) => {
    if (v || [false, 0].includes(v)) r[k] = v
  })

  return r
}, {})

console.log(result)

Use Array.prototype.filter() method to filter out the empty, null or undefined objects. Then using Array.prototype.map() make a key-value pair array. At last, use Object.fromEntries() method to transform it to a single object.

const fields = [
  { givenName: 'firstName' },
  { familyName: 'lastName' },
  { 'custom:data': 'blabla' },
  { 'custom:data2': '' },
  { 'custom:data3': null },
];
const ret = Object.fromEntries(
  fields
    .filter((x) => {
      const value = Object.values(x)[0];
      return value || value === false || value === 0 || Object.is(value, NaN);
    })
    .map((x) => [Object.keys(x)[0], Object.values(x)[0]])
);
console.log(ret);

It might help you.

const fields = [
    { givenName: 'firstName' },
    { familyName: 'lastName' },
    { 'custom:data': 'blabla' },
    { 'custom:data2': '' },
    { 'custom:data3': null },
  ];
  
 let item = {};

for ( let i = 0; i < fields.length; i++ ){
  for (const [key, value] of Object.entries(fields[i])) {
   if ( value !== null && value !== '' )
      item [key] = value;
  }
 
}

 console.log(item);

Works with one key, simple modification can work on n keys.

const fields = [
    { givenName: "firstName" },
    { familyName: "lastName" },
    { "custom:data": "blabla" },
    { "custom:data2": "" },
    { "custom:data3": null },
];

const reduced = fields
    .filter((f) => {
        const key = Object.keys(f)[0];
        return f[key] === "" || f[key] === null || f[key] === undefined
            ? false
            : true;
    })
    .reduce((acc, curr) => {
        const key = Object.keys(curr)[0];
        acc[key] = curr[key];
        return acc;
    }, {});

console.log(reduced);

发布评论

评论列表(0)

  1. 暂无评论