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

javascript - Remove specific properties from all objects in parentchild-relationship of arbitrary depth - Stack Overflow

programmeradmin0浏览0评论

I have a JavaScript object that represents a parent-child relationship of arbitrary depth. How can I remove certain properties for ALL objects?

var persons = [{
    name: 'hans',
    age: 25,
    idontwantthis: {
      somevalue: '123'
    },
    children: [{
        name: 'hans sohn',
        age: 8,
        idontwantthiseither: {
            somevalue: '456'
        },
        children: [{
            name: 'hans enkel',
            age: 2,
            children: []
        }]
    }]
}];

I only want the properties name, age and children and get rid of all the others. The new Array should look like this:

var persons = [{
    name: 'hans',
    age: 25,
    children: [{
        name: 'hans sohn',
        age: 8,
        children: [{
            name: 'hans enkel',
            age: 2,
            children: []
        }]
    }]
}];

I have a JavaScript object that represents a parent-child relationship of arbitrary depth. How can I remove certain properties for ALL objects?

var persons = [{
    name: 'hans',
    age: 25,
    idontwantthis: {
      somevalue: '123'
    },
    children: [{
        name: 'hans sohn',
        age: 8,
        idontwantthiseither: {
            somevalue: '456'
        },
        children: [{
            name: 'hans enkel',
            age: 2,
            children: []
        }]
    }]
}];

I only want the properties name, age and children and get rid of all the others. The new Array should look like this:

var persons = [{
    name: 'hans',
    age: 25,
    children: [{
        name: 'hans sohn',
        age: 8,
        children: [{
            name: 'hans enkel',
            age: 2,
            children: []
        }]
    }]
}];
Share Improve this question asked Nov 24, 2016 at 18:55 CodingKoboldCodingKobold 1771 silver badge10 bronze badges 4
  • 1 use recursion.... – Pranav C Balan Commented Nov 24, 2016 at 18:56
  • you could have use _.pick method but it won't help you now – Mahi Commented Nov 24, 2016 at 19:32
  • codereview.stackexchange./questions/57976/… – Mahi Commented Nov 24, 2016 at 19:37
  • @CodingKobold did you see my solution? It does what you're asking. Hope it helps! – HenryDev Commented Nov 24, 2016 at 20:25
Add a ment  | 

5 Answers 5

Reset to default 3

Do it with recursion and use Array#forEach method for iteration, Object.keys method for getting property name array,delete for deleting certain property of an object , typeof for checking it's an object and Array.isArray for checking array or not.

// hash map for storing properties which are needed to keep
// or use an array and use `indexOf` or `includes` method
// to check but better one would be an object    
var keep = {
  name: true,
  age: true,
  children: true
}


function update(obj, kp) {
  // check its an array
  if (Array.isArray(obj)) {
    // if array iterate over the elment
    obj.forEach(function(v) {
      // do recursion
      update(v, kp);
    })
  // check element is an object
  } else if (typeof obj == 'object') {
    // iterate over the object keys
    Object.keys(obj).forEach(function(k) {
      // check key is in the keep list or not
      if (!kp[k])
        // if not then delete it
        delete obj[k];
      else
        // otherwise do recursion
        update(obj[k], kp);
    })
  }
}

update(persons, keep);

var persons = [{
  name: 'hans',
  age: 25,
  idontwantthis: {
    somevalue: '123'
  },
  children: [{
    name: 'hans sohn',
    age: 8,
    idontwantthiseither: {
      somevalue: '456'
    },
    children: [{
      name: 'hans enkel',
      age: 2,
      children: []
    }]
  }]
}];

var keep = {
  name: true,
  age: true,
  children: true
}


function update(obj, kp) {
  if (Array.isArray(obj)) {
    obj.forEach(function(v) {
      update(v, kp);
    })
  } else if (typeof obj == 'object') {
    Object.keys(obj).forEach(function(k) {
      if (!kp[k])
        delete obj[k];
      else
        update(obj[k], kp);
    })
  }
}

update(persons, keep);

console.log(persons);

just use _.pick and recursion

_.map(persons, function pickPerson(person) {
    return _.chain(person)
        .pick(['name', 'age']) // pick needed props
        .merge({
            children: _.map(person.children, pickPerson) // go to depth
        })
        .value();
});

You should use recursion, basically you would create a function that iterates through your object's properties and calls itself recursively if it either finds an array or a property in the whitelist of properties that you provide to it.

A function like this would do the trick:

/**
 * Recursively modifies the provided object in place to delete the properties that don't appear in the `properties` whitelist.
 *
 * @method isolateProperties
 * @param {Object} object - Object to modify.
 * @param {Array|String} properties - An array of strings (or a single string) containing the names of the properties to whitelist.
 */
function isolateProperties(object, properties) { /* ES 5 */
    /* if properties is not an array transform it into an array */
    if (!(properties instanceof Array)) {
        properties = [properties];
    }

    /* if the object is an array, recurse over its elements */
    if (object instanceof Array) {
        for (var i = 0, n = object.length; i < n; ++i) {
            /* recurse */
            isolateProperties(object[i], properties);
        }
    } else {
        /* recurse through the object's properties and recurse the ones that are in the properties array; delete the rest */
        for (var key in object) {
            /* avoid potential for hackery */
            if (object.hasOwnProperty(key)) {
                if (properties.indexOf(key) > -1) { /* properties contains the key */
                    /* recurse */
                    isolateProperties(object[key], properties);
                } else {
                    /* delete the property */
                    delete object[key];
                }
            }
        }
    }
}

and you would use it like so:

var persons = [{
    name: 'hans',
    age: 25,
    idontwantthis: {
        somevalue: '123'
    },
    children: [{
        name: 'hans sohn',
        age: 8,
        idontwantthiseither: {
            somevalue: '456'
        },
        children: [{
            name: 'hans enkel',
            age: 2,
            children: []
        }]
    }]
}];

isolateProperties(persons, ['name', 'age', 'children']);

If you are working with modern browsers here's the ES2015 Version:

/**
 * Recursively modifies the provided object in place to delete the properties that don't appear in the `properties` whitelist.
 *
 * @method isolateProperties
 * @param {Object} object - Object to modify.
 * @param {Array|String} properties - An array of strings (or a single string) containing the names of the properties to whitelist.
 */
function isolateProperties(object, properties) { /* ES 6 */
    /* if properties is not an array transform it into an array */
    if (!Array.isArray(properties)) {
        properties = [properties];
    }

    /* if the object is an array, recurse over its elements */
    if (Array.isArray(object)) {
        object.forEach(element => isolateProperties(element, properties));
    } else {
        /* get the object's keys */
        const keys = Object.keys(object);
        /* recurse through the keys and recurse the ones that are in the properties array; delete the rest */
        keys.forEach(key => {
            if (properties.includes(key)) {
                /* recurse */
                isolateProperties(object[key], properties);
            } else {
                /* delete the property */
                delete object[key];
            }
        });
    }
}

A generic lodash solution that receives an array of props (like _.pick()), transforms the array, picks the properties for each object, and if one of the properties is an array, runs pickDeep recursively on the array:

function pickDeep(arr, propsToKeep) {
  return _.map(arr, function(obj) {
    return _(obj).pick(propsToKeep).mapValues(function(value) {
      return _.isArray(value) ? pickDeep(value, propsToKeep) : value;
    });
  });
}

var persons = [{
  name: 'hans',
  age: 25,
  idontwantthis: {
    somevalue: '123'
  },
  children: [{
    name: 'hans sohn',
    age: 8,
    idontwantthiseither: {
      somevalue: '456'
    },
    children: [{
      name: 'hans enkel',
      age: 2,
      children: []
    }]
  }]
}];

var result = pickDeep(persons, ['name', 'age', 'children']);

console.log(result);
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.2/lodash.js"></script>

And an ES6 version that uses Object.entries(), and Array.prototype.reduce() to iterate the objects properties, pick the required ones, and run pickDeep on arrays it finds:

const pickDeep = (arr, propsToKeep) => {
  const propsToKeepDict = new Set(propsToKeep);

  const inner = (arr) =>
    arr.map((obj) =>
      Object.entries(obj).reduce((result, [key, value]) => {
        propsToKeepDict.has(key) && (result[key] = Array.isArray(value) ? inner(value) : value);

        return result;
      }, {}));

  return inner(arr);
}

const persons = [{
  name: 'hans',
  age: 25,
  idontwantthis: {
    somevalue: '123'
  },
  children: [{
    name: 'hans sohn',
    age: 8,
    idontwantthiseither: {
      somevalue: '456'
    },
    children: [{
      name: 'hans enkel',
      age: 2,
      children: []
    }]
  }]
}];

const result = pickDeep(persons, ['name', 'age', 'children']);

console.log(result);

Here's a simple solution. No library required. Just Plain Javascript. Hope it helps!

var persons = [{
    name: 'hans',
    age: 25,
    idontwantthis: {
      somevalue: '123'
    },
    children: [{
        name: 'hans sohn',
        age: 8,
        idontwantthiseither: {
            somevalue: '456'
        },
        children: [{
            name: 'hans enkel',
            age: 2,
            children: []
        }]
    }]
}];

for(var i in persons){
  for(var j in persons[i]){
      var propertyName = j;
     if(propertyName !== "name" && propertyName !== "age" && propertyName !== "children"){
       delete persons[i][propertyName];
    } 
      if(propertyName === "children"){
          for(var k in persons[i][propertyName]){
              propertyName2 = k;
              for(var z in persons[i][propertyName][k]){
              propertyName3 = z; 
               if(propertyName3 === "idontwantthiseither"){
                delete persons[i][propertyName][k][propertyName3]
               }
              }
          }
      }
  }
}
console.log(persons);

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论