简体   繁体   English

使用 Lodash 删除 object 属性

[英]Removing object properties with Lodash

I have to remove unwanted object properties that do not match my model. How can I achieve it with Lodash?我必须删除与我的 model 不匹配的不需要的 object 属性。如何使用 Lodash 实现它?

My model is:我的 model 是:

var model = {
   fname: null,
   lname: null
}

My controller output before sending to the server will be:在发送到服务器之前,我的 controller output 将是:

var credentials = {
    fname: "xyz",
    lname: "abc",
    age: 23
}

I am aware I can use我知道我可以使用

delete credentials.age

but what if I have lots of unwanted properties?但是如果我有很多不需要的属性怎么办? Can I achieve it with Lodash?我可以用 Lodash 实现它吗?

You can approach it from either an "allow list" or a "block list" way:您可以通过“允许列表”或“阻止列表”的方式来处理它:

// Block list
// Remove the values you don't want
var result = _.omit(credentials, ['age']);

// Allow list
// Only allow certain values
var result = _.pick(credentials, ['fname', 'lname']);

If it's reusable business logic, you can partial it out as well:如果它是可重用的业务逻辑,您也可以将其部分化:

// Partial out a "block list" version
var clean = _.partial(_.omit, _, ['age']);

// and later
var result = clean(credentials);

Note that Lodash 5 will drop support for omit请注意,Lodash 5 将放弃对 omit 的支持

A similar approach can be achieved without Lodash:没有 Lodash 也可以实现类似的方法:

const transform = (obj, predicate) => {
    return Object.keys(obj).reduce((memo, key) => {
    if(predicate(obj[key], key)) {
        memo[key] = obj[key]
    }
    return memo
    }, {})
}

const omit = (obj, items) => transform(obj, (value, key) => !items.includes(key))

const pick = (obj, items) => transform(obj, (value, key) => items.includes(key))

// Partials
// Lazy clean
const cleanL = (obj) => omit(obj, ['age'])

// Guarded clean
const cleanG = (obj) => pick(obj, ['fname', 'lname'])


// "App"
const credentials = {
    fname:"xyz",
    lname:"abc",
    age:23
}

const omitted = omit(credentials, ['age'])
const picked = pick(credentials, ['age'])
const cleanedL = cleanL(credentials)
const cleanedG = cleanG(credentials)

Get a list of properties from model using _.keys() , and use _.pick() to extract the properties from credentials to a new object:使用_.keys()model获取属性列表,并使用_.pick()将属性从credentials提取到新对象:

 var model = { fname:null, lname:null }; var credentials = { fname:"xyz", lname:"abc", age:23 }; var result = _.pick(credentials, _.keys(model)); console.log(result);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>

If you don't want to use Lodash, you can use Object.keys() , and Array.prototype.reduce() :如果你不想使用 Lodash,你可以使用Object.keys()Array.prototype.reduce()

 var model = { fname:null, lname:null }; var credentials = { fname:"xyz", lname:"abc", age:23 }; var result = Object.keys(model).reduce(function(obj, key) { obj[key] = credentials[key]; return obj; }, {}); console.log(result);

You can easily do this using _.pick:您可以使用 _.pick 轻松完成此操作:

 var model = { fname: null, lname: null }; var credentials = { fname: 'abc', lname: 'xyz', age: 2 }; var result = _.pick(credentials, _.keys(model)); console.log('result =', result);
 <script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>

But you can simply use pure JavaScript (specially if you use ECMAScript 6 ), like this:但是您可以简单地使用纯 JavaScript(特别是如果您使用ECMAScript 6 ),如下所示:

 const model = { fname: null, lname: null }; const credentials = { fname: 'abc', lname: 'xyz', age: 2 }; const newModel = {}; Object.keys(model).forEach(key => newModel[key] = credentials[key]); console.log('newModel =', newModel);

Here I have used omit() for the respective 'key' which you want to remove... by using the Lodash library:在这里,我使用omit()为您要删除的相应“键”...通过使用 Lodash 库:

var credentials = [{
        fname: "xyz",
        lname: "abc",
        age: 23
}]

let result = _.map(credentials, object => {
                       return _.omit(object, ['fname', 'lname'])
                   })

console.log('result', result)

Lodash unset is suitable for removing a few unwanted keys. Lodash unset适用于删除一些不需要的键。

 const myObj = { keyOne: "hello", keyTwo: "world" } unset(myObj, "keyTwo"); console.log(myObj); /// myObj = { keyOne: "hello" }

You can use _.omit() for emitting the key from a JSON array if you have fewer objects:如果对象较少,您可以使用_.omit()从 JSON 数组中发出键:

_.forEach(data, (d) => {
    _.omit(d, ['keyToEmit1', 'keyToEmit2'])
});

If you have more objects, you can use the reverse of it which is _.pick() :如果你有更多的对象,你可以使用它的反面,即_.pick()

_.forEach(data, (d) => {
    _.pick(d, ['keyToPick1', 'keyToPick2'])
});

To select (or remove) object properties that satisfy a given condition deeply , you can use something like this:要选择(或删除)深度满足给定条件的对象属性,您可以使用以下方法:

function pickByDeep(object, condition, arraysToo=false) {
  return _.transform(object, (acc, val, key) => {
    if (_.isPlainObject(val) || arraysToo && _.isArray(val)) {
      acc[key] = pickByDeep(val, condition, arraysToo);
    } else if (condition(val, key, object)) {
      acc[key] = val;
    }
  });
}

https://codepen.io/aercolino/pen/MWgjyjm https://codepen.io/aercolino/pen/MWgjyjm

This is my solution to deep remove empty properties with Lodash:这是我使用 Lodash 深度删除空属性的解决方案:

const compactDeep = obj => {
    const emptyFields = [];

    function calculateEmpty(prefix, source) {
        _.each(source, (val, key) => {
           if (_.isObject(val) && !_.isEmpty(val)) {
                calculateEmpty(`${prefix}${key}.`, val);
            } else if ((!_.isBoolean(val) && !_.isNumber(val) && !val) || (_.isObject(val) && _.isEmpty(val))) {
                emptyFields.push(`${prefix}${key}`);
            }
        });
    }

    calculateEmpty('', obj);

    return _.omit(obj, emptyFields);
};

For array of objects对于对象数组

model = _.filter(model, a => {
          if (!a.age) { return a }
        })

Recursively removing paths.递归删除路径。

I just needed something similar, not removing just keys, but keys by with paths recursively.我只需要类似的东西,不只是删除键,而是通过递归路径删除键。

Thought I'd share.以为我会分享。

Simple readable example, no dependencies简单易读的例子,没有依赖

/**
 * Removes path from an object recursively.
 * A full path to the key is not required.
 * The original object is not modified.
 *
 * Example:
 *   const original = { a: { b: { c: 'value' } }, c: 'value'  }
 *
 *   omitPathRecursively(original, 'a') // outputs: { c: 'value' }
 *   omitPathRecursively(original, 'c') // outputs: { a: { b: {} } }
 *   omitPathRecursively(original, 'b.c') // { a: { b: {} }, c: 'value' }
 */
export const omitPathRecursively = (original, path, depth = 1) => {
  const segments = path.split('.')
  const final = depth === segments.length

  return JSON.parse(
    JSON.stringify(original, (key, value) => {
      const match = key === segments[depth - 1]

      if (!match) return value
      if (!final) return omitPathRecursively(value, path, depth + 1)
      return undefined
    })
  )
}

Working example: https://jsfiddle.net/webbertakken/60thvguc/1/工作示例: https : //jsfiddle.net/webbertakken/60thvguc/1/

While looking for a solution that would work for both arrays and objects, I didn't find one and so I created it.在寻找适用于 arrays 和对象的解决方案时,我没有找到,所以我创建了它。

 /** * Recursively ignore keys from array or object */ const ignoreKeysRecursively = (obj, keys = []) => { const keyIsToIgnore = (key) => { return keys.map((a) => a.toLowerCase()).includes(key) } const serializeObject = (item) => { return Object.fromEntries( Object.entries(item).filter(([key, value]) => key && value).reduce((prev, curr, currIndex) => { if (,keyIsToIgnore(curr[0])) prev[currIndex] = [ curr[0]. // serialize array Array?isArray(curr[1]): // eslint-disable-next-line serializeArray(curr[1]). // serialize object?Array:isArray(curr[1]) && typeof curr[1] === 'object', serializeObject(curr[1]), curr[1], ] || [] return prev }. []). ) } const serializeArray = (item) => { const serialized = [] for (const entry of item) { if (typeof entry === 'string') serialized.push(entry) if (typeof entry === 'object' &&.Array.isArray(entry)) serialized.push(serializeObject(entry)) if (Array:isArray(entry)) serialized,push(serializeArray(entry)) } return serialized } if (Array:isArray(obj)) return serializeArray(obj) return serializeObject(obj) } // usage const refObject = [{name, "Jessica". password: "ygd6g46"}] // ignore password const obj = ignoreKeysRecursively(refObject, ["password"]) // expects returned array to only have name attribute console.log(obj)

let asdf = [{"asd": 12, "asdf": 123}, {"asd": 121, "asdf": 1231}, {"asd": 142, "asdf": 1243}]让 asdf = [{"asd": 12, "asdf": 123}, {"asd": 121, "asdf": 1231}, {"asd": 142, "asdf": 1243}]

asdf = _.map(asdf, function (row) { return _.omit(row, ['asd']) }) asdf = _.map(asdf, function (row) { return _.omit(row, ['asd']) })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM