如何过滤子对象的属性,并返回通过Java过滤器的子对象的父对象?

时间:2019-04-25 03:48:32

标签: javascript ecmascript-6

我想对children对象的属性进行过滤,并通过过滤器返回带有孩子的父母。

我尝试将Array.filter,Array.some和Object.values组合使用,但是我想不出一种方法,一旦我使用Object.values就可以找回密钥。

var data = {
    parent1: {
        child1: {
            source: true
        },
        child2: {
            source: true
        }
    },
    parent2: {
        child3: {
            source: true
        },
        child4: {
            source: false
        }
    },
    parent3: {
        child5: {
                source: false
        }
    }
}

我希望结果是:

var afterFilter = {
    parent1: {
        child1: {
            source: true
        },
        child2: {
            source: true
        }
    },
    parent2: {
        child3: {
            source: true
        }
    }
}

5 个答案:

答案 0 :(得分:0)

对于每个父级,请使用 Array.reduce Object.entries 尝试此操作< em> entry 遍历父对象的子对象,并基于source对其进行过滤。

如果父级的当前子级的源为true,则将其添加到reduce的累加器acc中,否则忽略它:

const data = {parent1:{child1:{source:true},child2:{source:true}},parent2:{child3:{source:true},child4:{source:false}},parent3:{child5:{source:false}}};

const res = Object.entries(data).reduce((acc, [key, value]) =>{
  for(child in value){ //value is the child-object of the parent, iterating throgh all the key of the child and checking if the source is true for this key of the child
    if(value[child].source){
      acc[key] = {...acc[key], [child] : value[child]}; //using spread operator to preserve previous values
    }
  }
  return acc;
}, {});
console.log(res);

答案 1 :(得分:0)

除了使用Array方法,您还可以尝试一个简单的for...of循环:

var data = {
  parent1: {
    child1: {
      source: true
    },
    child2: {
      source: true
    }
  },
  parent2: {
    child3: {
      source: true
    },
    child4: {
      source: false
    }
  },
  parent3: {
    child5: {
      source: false
    }
  }
}

var afterFilter = {};

for (const [key, value] of Object.entries(data)){

  for (const [k, v] of Object.entries(value)){

    const { source } = v;

    if (source !== true)
      continue;

    // If `afterFilter[key]` does not exist, init with {}
    afterFilter[key] = afterFilter[key] || {};
    afterFilter[key][k] = { source };

  }

}

console.log(afterFilter)

答案 2 :(得分:0)

如果您发现自己的孩子是真实的并返回该父母,那也许对您来说是正确的答案

const data = [
{ name: 'parent1', parent : { child: { source : true } } },
{ name: 'parent2', parent : { child: { source : true } } },
{ name: 'parent3', parent : { child: { source : false } } }

];

const newData = data.filter((e)=> e.parent.child.source === true);
console.log(newData);

答案 3 :(得分:0)

这是我的解决方案。试试这个

var data = {
    parent1: {
        child1: {
            source: true
        },
        child2: {
            source: true
        }
    },
    parent2: {
        child3: {
            source: true
        },
        child4: {
            source: false
        }
    },
    parent3: {
        child5: {
                source: false
        }
    }
}

var afterFilter = {}


for(var key in data){

    for(var childkey in data[key]){

        if(data[key][childkey].source){

            if(afterFilter[key])
                afterFilter[key][childkey] = data[key][childkey]
            else
                afterFilter[key] = {[childkey]: data[key][childkey]}

        }
            
    }

}

console.log(afterFilter);

答案 4 :(得分:0)

如果您想要一个具有可重用功能的解决方案,建议您查看此实现。

const data = {parent1:{child1:{source:true},child2:{source:true}},parent2:{child3:{source:true},child4:{source:false}},parent3:{child5:{source:false}}}

function objectMapReduce (object, map, filter) {
  // iterate key-value pairs of object
  return Object.entries(object).reduce(
    (accumulator, [key, value]) => {
      // map each value in object
      const result = map(value, key, object)
      // filter each mapped value
      return filter(result, key, object)
        ? Object.assign(accumulator, { [key]: result })
        : accumulator
    },
    // initial value of accumulator
    {}
  )
}

const afterFilter = objectMapReduce(
  data, // map-reduce each parent in data
  parent => objectMapReduce(
    parent, // map-reduce each child in parent
    ({ source}) => ({ source }), // copy each child
    ({ source }) => source // keep child if source is true
  ),
  parent => Object.keys(parent).length > 0 // keep non-empty parent
)

console.log(afterFilter)