Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从任意深度的父/子关系中的所有对象中删除特定属性_Javascript_Arrays_Tree_Lodash - Fatal编程技术网

Javascript 从任意深度的父/子关系中的所有对象中删除特定属性

Javascript 从任意深度的父/子关系中的所有对象中删除特定属性,javascript,arrays,tree,lodash,Javascript,Arrays,Tree,Lodash,我有一个JavaScript对象,它表示任意深度的父子关系。如何删除所有对象的某些属性 var persons = [{ name: 'hans', age: 25, idontwantthis: { somevalue: '123' }, children: [{ name: 'hans sohn', age: 8, idontwantthiseither: { some

我有一个JavaScript对象,它表示任意深度的父子关系。如何删除所有对象的某些属性

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 persons = [{
    name: 'hans',
    age: 25,
    children: [{
        name: 'hans sohn',
        age: 8,
        children: [{
            name: 'hans enkel',
            age: 2,
            children: []
        }]
    }]
}];
使用迭代方法、获取属性名称数组的方法、删除对象的某些属性的方法、检查对象是否为对象的方法以及检查数组是否为数组的方法来执行此操作

// 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个人=[{
名字:“汉斯”,
年龄:25岁,
我不想这样:{
somevalue:'123'
},
儿童:[{
姓名:"孙汉斯",,
年龄:8岁,
我不想这样做:{
somevalue:'456'
},
儿童:[{
姓名:“汉斯·恩克尔”,
年龄:2岁,
儿童:[]
}]
}]
}];
变量保持={
姓名:对,
年龄:对,
孩子们:没错
}
功能更新(obj、kp){
if(数组isArray(obj)){
目标forEach(功能(v){
更新(v,kp);
})
}else if(对象的类型=='object'){
Object.keys(obj.forEach)(函数(k){
如果(!kp[k])
删除obj[k];
其他的
更新(obj[k],kp);
})
}
}
更新(人员,保持);

控制台日志(人)这里有一个简单的解决方案不需要库。只是简单的Javascript。希望有帮助

var个人=[{
名字:“汉斯”,
年龄:25岁,
我不想这样:{
somevalue:'123'
},
儿童:[{
姓名:"孙汉斯",,
年龄:8岁,
我不想这样做:{
somevalue:'456'
},
儿童:[{
姓名:“汉斯·恩克尔”,
年龄:2岁,
儿童:[]
}]
}]
}];
适用于(以个人为单位的var i){
对于(以个人[i]为单位的风险值j){
var-propertyName=j;
if(propertyName!==“name”&&propertyName!==“age”&&propertyName!==“children”){
删除人员[i][propertyName];
} 
如果(propertyName==“子项”){
对于(个人[i][propertyName]中的风险值k){
propertyName2=k;
对于(个人[i][propertyName][k]中的var z){
propertyName3=z;
如果(propertyName3==“IdontWantThis”){
删除个人[i][propertyName][k][propertyName3]
}
}
}
}
}
}

控制台日志(人)只需使用即可。选择和递归

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

您应该使用递归,基本上您将创建一个函数,该函数迭代对象的属性,并在您提供给它的属性白名单中找到数组或属性时递归调用自身

这样的函数可以实现以下功能:

/**
 * 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];
                }
            }
        }
    }
}
如果您使用的是现代浏览器,以下是ES2015版本:

/**
 * 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];
            }
        });
    }
}

一个通用的lodash解决方案,它接收一个道具数组(如
..pick()
),变换数组,为每个对象拾取属性,如果其中一个属性是数组,则在数组上递归运行
pickDeep

功能pickDeep(arr、propsToKeep){
返回映射(arr,函数(obj){
返回j(obj).pick(propstokep).mapValues(函数值){
return u.isArray(value)→pickDeep(value,propstokep):value;
});
});
}
个人变量=[{
名字:“汉斯”,
年龄:25岁,
我不想这样:{
somevalue:'123'
},
儿童:[{
姓名:"孙汉斯",,
年龄:8岁,
我不想这样做:{
somevalue:'456'
},
儿童:[{
姓名:“汉斯·恩克尔”,
年龄:2岁,
儿童:[]
}]
}]
}];
var结果=pickDeep(个人,['name','age','children']);
控制台日志(结果)

使用递归….您可以使用
\拾取方法
,但它对您没有帮助now@CodingKobold你看到我的解决方案了吗?它能满足你的要求。希望有帮助!我不想这两个都还在there@Mahi我认为解决方案应该去掉一个不是名字、年龄和孩子的属性。简单地说,删除“我不想这样”。我的解决方案就是这样做的。我正在删除“Idont want this”,但我不想这两个都是,抱歉,伙计,我弄糊涂了,没有看到有Idont want这两个属性。谢谢你告诉我:)@Mahi我刚刚更新了我的解决方案。现在它工作得很好,解决方案很好。但是,如果嵌套数组不在
子对象中,它将不起作用key@Mahi问题条件:“我只想要房产的名称、年龄和孩子,而不想要其他的。”我不关心其他属性,但如果嵌套对象位于'name'键中,而不是
子项中,那么它们的问题就在这里。@Mahi没有相关信息。如果作者愿意,他可以进行验证,并且OP说,
任意深度
,但这不会超过3个深度。是的,它可以在任何类型的数组或深度中工作。:)@玛希:是的;)我认为库不以递归的方式来处理,这就是为什么它们没有递归的原因
/**
 * 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];
            }
        });
    }
}