如何使用动态过滤器过滤javascript对象

cmssoen2  于 2021-09-13  发布在  Java
关注(0)|答案(7)|浏览(574)

我有一个javascript对象和id数组:

var ids = [46,44,49,47];
var obj = {
        "46": {
            "group": "A",
            "temp": 26,
            "humid": 36
        },
        "44": {
            "group": "B",
            "temp": 19,
            "humid": 32
        },
        "49": {
            "group": "B",
            "temp": 20,
            "humid": 31
        },
        "47": {
            "group": "A",
            "temp": 24,
            "humid": 32
        }
    };

我想得到平均数 'temp''group' . 我该怎么做?
我发现其他的例子可以解决这个问题,但是,这些例子假设 'group' 永远都是一样的。就我而言, 'group' 世界总是在变化。
所以本质上我需要找到存在多少个独特的组,然后返回平均值 'temp' 每一个的价值。
我尝试使用一些嵌套在一起的for循环,但很快就变得复杂了。。。
预期产出: avgTemps = {"A":25, "B": 19.5}

7gcisfzg

7gcisfzg1#

在第一步中,您将获得数据中存在的唯一组名列表。然后,过滤出每组的温度并计算平均值。
还可以使用lodash函数从列表中删除重复条目( _.uniq )和对一组数字求和( _.sum ).

var ids = [46,44,49,47];
var obj = {
        "46": {
            "group": "A",
            "temp": 26,
            "humid": 36
        },
        "44": {
            "group": "B",
            "temp": 19,
            "humid": 32
        },
        "49": {
            "group": "B",
            "temp": 20,
            "humid": 31
        },
        "47": {
            "group": "A",
            "temp": 24,
            "humid": 32
        }
    };
function onlyUnique(value, index, self) {
  return self.indexOf(value) === index;
}

let groups = Object.values(obj).map((o)=>o.group).filter(onlyUnique)
for (let group of groups) {
  let temps = Object.values(obj).filter((o)=>o.group===group).map((o)=>o.temp)
  let avgtmp = temps.reduce((pv, cv) => pv + cv, 0)/temps.length;
  console.log(`group ${group} has an avg tmp of ${avgtmp}`)
}

// OUTPUT
// group B has an avg tmp of 19.5
// group A has an avg tmp of 25
hgqdbh6s

hgqdbh6s2#

你可以用 Object.keys(obj) 获取组的每个ID。
然后,您可以从以下组中获取值:

const obj = {
        "46": {
            "group": "A",
            "temp": 26,
            "humid": 36
        },
        "44": {
            "group": "B",
            "temp": 19,
            "humid": 32
        },
        "49": {
            "group": "B",
            "temp": 20,
            "humid": 31
        },
        "47": {
            "group": "A",
            "temp": 24,
            "humid": 32
        }
    };

Object.keys(obj).map((id) => console.log(`Temp of id ${id} is ${obj[id].temp}`))

我们可以使用组值创建对象。
现在,如果您可以Mapobj,让我们创建每组的平均值。

const obj = {
            "46": {
                "group": "A",
                "temp": 26,
                "humid": 36
            },
            "44": {
                "group": "B",
                "temp": 19,
                "humid": 32
            },
            "49": {
                "group": "B",
                "temp": 20,
                "humid": 31
            },
            "47": {
                "group": "A",
                "temp": 24,
                "humid": 32
            }
        };
const groups = {};

Object.keys(obj).map((id) => {
  if(!!groups[obj[id].group]) {
    groups[obj[id].group].push(obj[id].temp);
  } else {
    groups[obj[id].group] = [obj[id].temp]
  }
})

console.log(groups)

最后我们可以计算平均温度。

const obj = {
            "46": {
                "group": "A",
                "temp": 26,
                "humid": 36
            },
            "44": {
                "group": "B",
                "temp": 19,
                "humid": 32
            },
            "49": {
                "group": "B",
                "temp": 20,
                "humid": 31
            },
            "47": {
                "group": "A",
                "temp": 24,
                "humid": 32
            }
        };
const groups = {};

Object.keys(obj).forEach((id) => {
  if(!!groups[obj[id].group]) {
    groups[obj[id].group].push(obj[id].temp);
  } else {
    groups[obj[id].group] = [obj[id].temp]
  }
})

function getAvg(grades) {
  const total = grades.reduce((acc, c) => acc + c, 0);
  return total / grades.length;
}

Object.keys(groups).forEach((group) => {
  groups[group] = getAvg(groups[group])
})

console.log(groups)
kzmpq1sx

kzmpq1sx3#

这应该稍微短一点:

let output = {};

 for (let group in obj) {
        const groupName = obj[group]['group'];
        if(!output[groupName]) {
            output[groupName] =  obj[group]['temp'];
         } else {
            output[groupName] = (output[groupName] + obj[group]['temp'])/2;
         }
 }
 console.log(output);
kiz8lqtg

kiz8lqtg4#

首先使用总和和计数创建目标对象,然后将其除以平均值:

function getAvgTemp(obj) {
    let data = Object.values(obj);
    let result = Object.fromEntries(data.map(({group}) => [group, { sum: 0, count: 0 }]));
    for (let {group, temp} of data) {
        let o = result[group];
        o.count++; 
        o.sum += temp;
    }
    for (let key of Object.keys(result)) {
        result[key] = result[key].sum / result[key].count;
    }
    return result;
}

// Demo    
var obj = {"46": {"group": "A","temp": 26,"humid": 36},"44": {"group": "B","temp": 19,"humid": 32},"49": {"group": "B","temp": 20,"humid": 31},"47": {"group": "A","temp": 24,"humid": 32}};
let avgTemp = getAvgTemp(obj);
console.log(avgTemp);

请注意 ids 数组似乎有些过分,因为对象的属性可以通过 Object.keys .

j7dteeu8

j7dteeu85#

功能性风格中的另一个示例)

function avg(vals: number[]): number {
    return vals.reduce((a, b) => a + b) / vals.length;
}

function groupBy<Item, Desc extends string | number>(descriminator: (item: Item) => Desc) {
    return (items: Item[]): Record<Desc, Item[]> => items.reduce((groups, item) => ({
        ...groups,
        [descriminator(item)]: [...(groups[descriminator(item)] || []), item]
    }), {} as Record<Desc, Item[]>);
}

function mapValues<From, To>(mapper: (from: From) => To) {
    return (record: Record<string, From>): Record<string, To> => Object.assign(
        {} as Record<string, To>,
        ...Object.keys(record).map(key => ({
            [key]: mapper(record[key])
        }))
    )
}

const groups = groupBy(
    ({ group }: Item) => group
)(
    Object.values(obj)
);

const avgTemps = mapValues(
    (groupItems: Item[]) => avg(groupItems.map(({ temp }) => temp))
)(
    groups
);

tsPlayground

6l7fqoea

6l7fqoea6#

首先,我把所有独特的群体放在一个集合中进行区分。然后创建一个对象数组,并最终将所有平均值、计数和总数分配到对象数组中。并生成了预期的结果。

var ids = [46, 44, 49, 47];
  var obj = {
    "46": {
      "group": "A",
      "temp": 26,
      "humid": 36
    },
    "44": {
      "group": "B",
      "temp": 19,
      "humid": 32
    },
    "49": {
      "group": "B",
      "temp": 20,
      "humid": 31
    },
    "47": {
      "group": "A",
      "temp": 24,
      "humid": 32
    }
  };
  var groups = new Set()
  Object.keys(obj).forEach(element => {
    groups.add(obj[element].group);
  });
  var tempAvgByGroups = [];
  const avgTemp = {}
  groups.forEach(element => {
    const groupObj = {
      "group": element,
      "average": 0,
      "count": 0,
      "total": 0,
    }
    Object.keys(obj).forEach(item => {
      if (element === obj[item]["group"]) {
        groupObj["count"] = groupObj["count"] + 1;
        groupObj["total"] = groupObj["total"] + obj[item]["temp"]
      }
    });
    groupObj["average"] = groupObj["total"] / groupObj["count"];
    tempAvgByGroups.push(groupObj);
    avgTemp[element] = groupObj["average"]
  });
  console.log(avgTemp);
mnowg1ta

mnowg1ta7#

你可以这样做:

const
  ids = [46,44,52,49,47]
, obj = 
    { '46': { group: 'A', temp: 26, humid: 36 } 
    , '44': { group: 'B', temp: 19, humid: 32 } 
    , '49': { group: 'B', temp: 20, humid: 31 } 
    , '47': { group: 'A', temp: 24, humid: 32 }
    , '64': { group: 'A', temp: 25, humid: 32 }
    }
, avgTemps =
    ids.reduce((rO,key)=>{if (obj[key]) rO.push(obj[key]);return rO},[])
      .reduce((res,o,_,Oe)=>
      {
      if(!res[o.group])
        {
        let grp = Oe.filter(x=>x.group===o.group)
                    .map(y=>y.temp)
        res[o.group] = grp.reduce((sum,t)=>sum+t,0) / grp.length
        }
      return res
      },{})

console.log( avgTemps )
.as-console-wrapper {max-height: 100%!important;top:0 }

相关问题