如何优雅的删除对象中的指定属性?

shiver
  • 58

问题:
请教各位大牛,如何优雅的删除如下数据结构中的所有created_at,deleted_at,updated_at字段?
图片描述

在node.js网管层想要干掉这些无用的字段

评论
阅读 23k
6 个回答
用JSON.stringify,看着还算优雅。
var d=JSON.parse(JSON.stringify(data,function(key,value){
    if(key=='created_at'||key=='deleted_at'||key=='updated_at'){
      return undefined;
    }else{
      return value;
    }
  }))

要优雅的话,使用 Lodash 的 omit 方法移除不要的属性:

const object = { 'a': 1, 'b': '2', 'c': 3 };
 
const result = _.omit(object, ['a', 'c']);
// => { 'b': '2' }

或者用 pick 方法只留下需要的属性:

const object = { 'a': 1, 'b': '2', 'c': 3 };
 
const result = _.pick(object, ['a', 'c']);
// => { 'a': 1, 'c': 3 }

当然如果你不想用库或者喜欢动手的话,自己实现一个 omit 也是可以的,实现方法有很多:

// 中规中矩式
const omit = (obj, uselessKeys) =>
   Object.keys(obj).reduce((acc, key) =>
      return uselessKeys.includes(key) ?
        acc : 
        {...acc, [key]: acc[key]}
   }, {});


// 投机取巧式
const omit = (obj, uselessKeys) =>
  uselessKeys.reduce((acc, key) => {
    return {...acc, [key]: undefined}
  }, obj)


// 粗暴式
const omit = (obj, uselessKeys) => {
  uselessKeys.forEach(key => {
    delete obj[key]
  })
  return obj
}

最后是特别粗暴的方法:

delete obj.created_at
delete obj.deleted_at
delete obj.updated_at

希望对你有帮助

使用lodash库的pick方法,指定返回的属性

JSON.parse( JSON.stringify( data ).replace( /("created_at":".?",)|("deleted_at":".?",)|(,"updated_at":".*?")/g, '' ) )

只针对如图数据,注意updated_at会出现在最后一位。

我来自己回答一下吧 这是当初提出这个问题后 最后采用的解决方法 一直用到了现在

import { isArray, isObject, forOwn, omit } from 'lodash';

const uselessParameters = ['created_at','deleted_at','updated_at'];

function omitDeepLodash(input: any, props: string[]): any {
    let p = props;
    function omitDeepOnOwnProps(obj: any) {
        if (!isArray(obj) && !isObject(obj)) {
            return obj;
        }

        if (isArray(obj)) {
            return omitDeepLodash(obj, p);
        }

        const o: any = {};
        forOwn(obj, (value, key) => {
            o[key] = omitDeepLodash(value, p);
        });

        return omit(o, p);
    }

    if (arguments.length > 2) {
        p = Array.prototype.slice.call(arguments).slice(1);
    }

    if (typeof input === 'undefined') {
        return {};
    }

    if (isArray(input)) {
        return input.map(omitDeepOnOwnProps);
    }

    return omitDeepOnOwnProps(input);
}

export function deleteParams(data: any) {
    return omitDeepLodash(data, uselessParameters);
}

graphql了解一下?

补充一下
题主的有嵌套结构的created_at,deleted_at等字段,因此我所知的库都不足以称之为优雅。
当然可以通过正则匹配去删除关键字(如果要删除其他的无用属性呢,会不会存在有些实体需要删除有些不用),或者遍历属性递归删除(效率不高),更有甚者可能是a.created_at需要删除a.b.created_at不需要。
因此我个人认为以schema定义返回结构的方式是最优雅的删除方式。

宣传栏