代码之家  ›  专栏  ›  技术社区  ›  Sreekanth Reddy Balne

对特定对象属性对应的所有值求和的健壮方法?

  •  2
  • Sreekanth Reddy Balne  · 技术社区  · 6 年前

    我有这样一个数组。

    
    items = [
      {
        "title": "title1",
        "category": "category1",
        "value": 200
      },
      {
        "title": "title2",
        "category": "category2",
        "value": 450
      },
      {
        "title": "title3",
        "category": "category1",
        "value": 100
      }
    ]
    

    此数组由许多具有属性的字典组成 category value . 总结如下:

    
    data= [
      {
        "category": "category1",
        "value": 300
      },
      {
        "category": "category2",
        "value": 450
      }
    ]
    

    我在寻找最好的算法或方法,既适用于小阵列,也适用于大阵列。如果有一个现有的算法,请指出我的来源。

    
    data = []
    for each item in items:
        if data has a dictionary with dictionary.category == item.category:
            data's dictionary.value = data's dictionary.value + item.value
        else:
            data.push({"category": item.category, "value":item.value})
    

    注:欢迎使用任何编程语言。请在投票前发表评论。

    4 回复  |  直到 6 年前
        1
  •  3
  •   Eddie    6 年前

    在javascript中,可以使用 reduce 将数组分组为对象。使用类别作为属性。使用 Object.values 将对象转换为数组。

    var items = [{
        "title": "title1",
        "category": "category1",
        "value": 200
      },
      {
        "title": "title2",
        "category": "category2",
        "value": 450
      },
      {
        "title": "title3",
        "category": "category1",
        "value": 100
      }
    ];
    
    var data = Object.values(items.reduce((c, v) => {
      c[v.category] = c[v.category] || {category: v.category,value: 0};
      c[v.category].value += v.value;
      return c;
    }, {}));
    
    console.log(data);
        2
  •  1
  •   Pablo Santa Cruz    6 年前

    您需要的是SQL group by 就像手术一样。通常,那些 操作是用哈希算法处理的。如果您的所有数据都可以放入内存(从小到大的数据结构),那么您可以非常快速地实现它。

    如果数据结构庞大,则需要使用中间内存(如硬盘或数据库)。

    一种简单的python方法是:

    data_tmp = {}
    for item in items:
        if item['category'] not in data_tmp:
            data_tmp[item['category']] = 0
        data_tmp[item['category']] += item['value']
    data = []
    for k, v in data_tmp.items():
        data.append({
            'category': k,
            'value': v
        })
    # done
    

    如果你想要更多的pythonic代码,你可以使用 defaultdict :

    from collections import defaultdict
    data_tmp = defaultdict(int)
    for item in items:
        data_tmp[item['category']] += item['value']
    data = []
    for k, v in data_tmp.items():
        data.append({
            'category': k,
            'value': v
        })
    # done
    
        3
  •  1
  •   Stuart    6 年前

    在Python中,Pandas可能是一种更方便、更高效的方法。

    import pandas as pd
    df = pd.DataFrame(items)
    sums = df.groupby("category", as_index=False).sum()
    data = sums.to_dict("records") 
    

    sums 作为一个数据帧,并像那样使用它,而不是转换回字典列表。

        4
  •  0
  •   vash_the_stampede    6 年前

    itertools.groupby组

    d = []
    
    lista = sorted(items, key=lambda x: x['category'])
    for k, g in groupby(lista, key=lambda x: x['category']):
        temp = {}
        temp['category'] = k
        temp['value'] = sum([i['value'] for i in list(g)])
        d.append(temp)
    
    print(d)
    # [{'category': 'category1', 'value': 300}, {'category': 'category2', 'value': 450}]