Javascript 将相同的键值聚合到一个数组中并避免未定义

Javascript 将相同的键值聚合到一个数组中并避免未定义,javascript,arrays,data-structures,reduce,Javascript,Arrays,Data Structures,Reduce,我试图按值将相同的键值聚合到一个数组中 例如,我有一个对象数组,如下所示 const data = [{foo: true},{foo: false},{bar: true},{buzz: false}] 当它们聚合时,数组将转换为 [ foo: {true: [{foo: true}], false: [{foo: false}]}, bar: {true: [{bar: true}]}, buzz: {false: [{buzz: false}]} ] 数组项是原始对象 现在我知道了我要

我试图按值将相同的键值聚合到一个数组中

例如,我有一个对象数组,如下所示

const data = [{foo: true},{foo: false},{bar: true},{buzz: false}]
当它们聚合时,数组将转换为

[
foo: {true: [{foo: true}], false: [{foo: false}]},
bar: {true: [{bar: true}]},
buzz: {false: [{buzz: false}]}
]
数组项是原始对象

现在我知道了我要分组的密钥。。 它们是foo、bar、buzz和fizz

但是fizz不是原始数组的一部分,因此返回值是未定义的,如下所示

[
foo: {true:[{foo: true}], false: [{foo: false}]},
bar: {true: [{bar: true}]},
buzz: {false: A[{buzz: false}]}
fizz: {undefined: [{foo: true},{foo: false},{bar: true},{buzz: false}]}
], 
如何减少原始数组而不包括未定义的fizz值

代码如下:

 let v = [];
let types = ['foo', 'bar', 'buzz', 'fizz' ]
    for (let x = 0; x < types.length; x++) {
        let data = data.reduce((acc, i) => {
            if (!acc[i[types[x]]]) {
                acc[i[types[x]]] = [i]
            }
            else if (Array.isArray(acc[i[types[x]]])) {
                acc[i[types[x]]].push(i);
            }
            else if (typeof acc[i[types[x]]] === 'object') {
                acc[i[types[x]]] = [acc[i[types[x]]]]
                acc[i[types[x]]].push(i)
            }
            return acc;
        }, {})
        v.push({ [types[x]]: data });
    }

    return v;
让v=[];
让类型=['foo','bar','buzz','fizz']
for(设x=0;x{
如果(!acc[i[types[x]]]){
acc[i[类型[x]]]=[i]
}
else if(Array.isArray(acc[i[types[x]]])){
acc[i[类型[x]]].推送(i);
}
else if(acc的类型[i[types[x]]]=='object'){
acc[i[类型[x]]]=[acc[i[类型[x]]]]
acc[i[类型[x]]].推送(i)
}
返回acc;
}, {})
v、 push({[types[x]]:data});
}
返回v;
尝试以下方法:

const data=[{foo:true},{foo:false},{bar:true},{buzz:false}];
设v=[];
让类型=['foo','bar','buzz','fizz'];
for(设x=0;x0){
for(设i=0;i控制台日志(v)假设您只想计算每个键的编号(例如
true
false
),则可以使用以下代码

我把它写成了一个名为“聚合”的函数,这样就可以用不同的参数多次调用它

const initialData=[{foo:true},{foo:true},{foo:false},{bar:true},{buzz:false}];
常量类型=['foo','bar','buzz','fizz'];
常量聚合=(数据、类型)=>{
const result={};
data.forEach(项=>{
//从对象中提取键和值
//注意:使用索引0,因为示例中的每个对象只有一个键
常量[键,值]=对象项(项)[0];
//检查结果是否已包含此键
如果(结果[键]){
如果(结果[键][值]){
//如果值已存在,请追加一个
结果[键][值]+;
}否则{
//创建新键并用值1实例化
结果[键][值]=1;
}
}否则{
//如果结果不包含键,则使用值1实例化
结果[键]={[值]:1};
}
});
返回结果;
};
log(聚合(初始数据、类型))看看它是如何工作的。这可能是构建方法的正确方法

解决OP问题的一种通用方法是迭代提供的
数据
数组。对于每一项,我们将提取其键和值。如果在另一个提供的
types
数组中列出(包括)项的键,则将继续创建新的数据结构,并在后者中收集当前处理的项

人们不希望迭代
类型
数组,因为每次处理
类型
项时,它都会导致对
数据
项进行不必要的复杂查找

因此,一个通用的(更好的代码重用)
reduce
方法可能是OP问题的最佳解决方案

const sampleDataList=[
{foo:true},
{foo:false},
{bar:true},
{baz:false},
{buzz:false},
{baz:false},
{bar:true}
];
//foo:{true:[{foo:true}],false:[{foo:false}]},
//条:{true:[{bar:true}]},
//嗡嗡声:{false:[{buzz:false}]}
函数collectItemIntoInclusiveKeyValueGroup(收集器,项){
const{inclusiveKeyList,index}=收集器;
const firstItemEntry=Object.entries(项)[0];
const key=firstItemEntry[0];
const isproceedCollection=(//继续收集。。。
//
!Array.isArray(inclusiveKeyList)//-对于没有给定的列表
||inclusiveKeyList.includes(key)//-或如果列出了项键。
);
如果(iSproceedCollection){
让keyGroup=index[key];//访问标识的组
如果(!keyGroup){//由项的键执行,…或。。。
//…创建它以防。。。
keyGroup=index[key]={};//……它还不存在。
}
const valueLabel=String(firstItemEntry[1]);//项值作为键。
让valueGroupList=keyGroup[valueLabel];//访问组列表
如果(!valueGroupList){//由项的
//价值,…或在中创建它
valueGroupList=keyGroup[valueLabel]=[];//如果它还不存在。
}
//将原始引用推送到一个分组中
//OP要求的键值列表。
valueGroupList.push(项目);
}
回程收集器;
}
console.log(
“‘foo’、‘bar’、‘buzz’和‘fizz’”,
sampleDataList.reduce(CollectionItemIntoInclusiveKeyValueGroup{
inclusiveKeyList:['foo'、'bar'、'buzz'、'fizz'],
索引:{}
}).索引
);
console.log(
“‘foo’、‘bar’和‘baz’”,
sampleDataList.reduce(CollectionItemIntoInclusiveKeyValueGroup{
inclusiveKeyList:['foo'、'bar'、'baz'],
索引:{}
}).索引
);
console.log(
“所有可用密钥:”,
sampleDataList.reduce(collec