代码之家  ›  专栏  ›  技术社区  ›  RogerHN

计算数组中每个值的对象数

  •  1
  • RogerHN  · 技术社区  · 6 年前

    var markers = [
      {
        "type":"Chocolate",
        "name":"KitKat",
        "group":"candy",
        "icon":"candy",
        "coords":[5246,8980],
      },
      {
        "type":"Fruit",
        "name":"Orange",
        "group":"fruits",
        "icon":"fruis",
        "coords":[9012,5493],
      },
      {
        "type":"Fruit",
        "name":"Banana",
        "group":"fruits",
        "icon":"fruis",
        "coords":[9012,5493],
      },
      {
        "type":"Food",
        "name":"Rice",
        "group":"foods",
        "icon":"foods",
        "coords":[6724,9556],
      },
      {
        "type":"Food",
        "name":"Meat",
        "group":"foods",
        "icon":"foods",
        "coords":[6724,9556],
      },
      {
        "type":"Food",
        "name":"Beam",
        "group":"foods",
        "icon":"foods",
        "coords":[6724,9556],
      },
      {
        "type":"Liquid",
        "name":"Water",
        "group":"liquids",
        "icon":"liquids",
        "coords":[6724,9556],
      },
      {
        "type":"Liquid",
        "name":"Coffe",
        "group":"liquids",
        "icon":"liquids",
        "coords":[6724,9556],
      },
    ]
    

    我想计算每个组在这个数组中有多少项。

    var count = []
    
    for (var i = 0; i < markers.length; i++) {
      count[markers[i].group] = count[markers[i].group] + 1 || 1 ;
    }
    

    它输出这个结果:

    count = [
    candy: 1
    foods: 3
    fruits: 2
    liquids: 2
    ]
    

    count = [
    {"item": "candy","qnt":1},
    {"item": "foods","qnt":3},
    {"item": "fruits","qnt":2},
    {"item": "liquids","qnt":2}
    ]
    

    我知道我可以这样做:

    var total_fruits = 0;
    for (var i = 0; i < markers.length; i++) {
      if (markers[i].group == "fruits"){
        total_fruits++
      }
    }
    

    但是想象一下,对于一组超过50种类型的人来说,我需要多少if。。。

    我将使用html部分中的值与项值类似的类:

    <ul>
      <li class="candy">
        <span class="qnt">1</span>
      </li>
      <li class="fruits">
        <span class="qnt">2</span>
      </li>
      <li class="foods">
        <span class="qnt">3</span>
      </li>
      <li class="liquids">
        <span class="qnt">2</span>
      </li>
    </ul>
    

    有什么建议或如何改进?

    9 回复  |  直到 6 年前
        1
  •  1
  •   zfrisch    6 年前

    你可以使用 reduce 方法返回包含项和数量的新数组。

    findIndex . 如果没有,我们用qnt值1推送新类型,如果没有,我们只是增加qnt值。

    markers.reduce((ms, m) => (ms.findIndex(o => o.item === m["group"]) > 0) ? 
    (ms[ms.findIndex(o => o.item === m["group"])]["qnt"]++, ms) : 
    (ms.push({  qnt: 1,  item: m["group"]}), ms), []);
    

    var markers=[{type:"Chocolate",name:"KitKat",group:"candy",icon:"candy",coords:[5246,8980]},{type:"Fruit",name:"Orange",group:"fruits",icon:"fruis",coords:[9012,5493]},{type:"Fruit",name:"Banana",group:"fruits",icon:"fruis",coords:[9012,5493]},{type:"Food",name:"Rice",group:"foods",icon:"foods",coords:[6724,9556]},{type:"Food",name:"Meat",group:"foods",icon:"foods",coords:[6724,9556]},{type:"Food",name:"Beam",group:"foods",icon:"foods",coords:[6724,9556]},{type:"Liquid",name:"Water",group:"liquids",icon:"liquids",coords:[6724,9556]},{type:"Liquid",name:"Coffe",group:"liquids",icon:"liquids",coords:[6724,9556]}];
    
    let r = markers.reduce((ms, m) => (ms.findIndex(o => o.item === m["group"]) > 0) ? 
    (ms[ms.findIndex(o => o.item === m["group"])]["qnt"]++, ms) : 
    (ms.push({  qnt: 1,  item: m["group"]}), ms), []);
    
    console.log(r);
        2
  •  4
  •   Mark    6 年前

    您可以使用一个步骤构建所需的对象 reduce() . 这将生成一个已设置关键帧的对象 group . 要仅获取数组,请使用 Object.values()

    var markers = [{"type":"Chocolate","name":"KitKat","group":"candy","icon":"candy","coords":[5246,8980],},{"type":"Fruit","name":"Orange","group":"fruits","icon":"fruis","coords":[9012,5493],},{"type":"Fruit","name":"Banana","group":"fruits","icon":"fruis","coords":[9012,5493],},{"type":"Food","name":"Rice","group":"foods","icon":"foods","coords":[6724,9556],},{"type":"Food","name":"Meat","group":"foods","icon":"foods","coords":[6724,9556],},{"type":"Food","name":"Beam","group":"foods","icon":"foods","coords":[6724,9556],},{"type":"Liquid","name":"Water","group":"liquids","icon":"liquids","coords":[6724,9556],},{"type":"Liquid","name":"Coffe","group":"liquids","icon":"liquids","coords":[6724,9556],},]
    
    let counts = markers.reduce((obj, {group}) => {
      if(!obj[group]) obj[group] = {"item": group, "qnt":1}  // make a count item if it doesn't exist
      else obj[group].qnt++                                  // or increment it
      return obj
    }, {})
    
    console.log(Object.values(counts))
        3
  •  2
  •   Taplar    6 年前

    var markers = [{
        "type": "Chocolate",
        "name": "KitKat",
        "group": "candy",
        "icon": "candy",
        "coords": [5246, 8980],
      },
      {
        "type": "Fruit",
        "name": "Orange",
        "group": "fruits",
        "icon": "fruis",
        "coords": [9012, 5493],
      },
      {
        "type": "Fruit",
        "name": "Banana",
        "group": "fruits",
        "icon": "fruis",
        "coords": [9012, 5493],
      },
      {
        "type": "Food",
        "name": "Rice",
        "group": "foods",
        "icon": "foods",
        "coords": [6724, 9556],
      },
      {
        "type": "Food",
        "name": "Meat",
        "group": "foods",
        "icon": "foods",
        "coords": [6724, 9556],
      },
      {
        "type": "Food",
        "name": "Beam",
        "group": "foods",
        "icon": "foods",
        "coords": [6724, 9556],
      },
      {
        "type": "Liquid",
        "name": "Water",
        "group": "liquids",
        "icon": "liquids",
        "coords": [6724, 9556],
      },
      {
        "type": "Liquid",
        "name": "Coffe",
        "group": "liquids",
        "icon": "liquids",
        "coords": [6724, 9556],
      }
    ];
    
    var temp = markers.reduce( function ( results, marker ) {
      results[ marker.group ] = ( results[ marker.group ] || 0 ) + 1;
      
      return results;
    }, {});
    
    //now convert the object to a list like you want it
    temp = Object.keys( temp ).map( function ( group ) {
      return { group: group, quantity: temp[ group ] };
    } );
    
    console.log( temp );
        4
  •  2
  •   Akrion    6 年前

    Array.reduce 分组 group Object.entries 具有 Array.map 要获得所需的输出格式,请执行以下操作:

    var data = [ { "type":"Chocolate", "name":"KitKat", "group":"candy", "icon":"candy", "coords":[5246,8980], }, { "type":"Fruit", "name":"Orange", "group":"fruits", "icon":"fruis", "coords":[9012,5493], }, { "type":"Fruit", "name":"Banana", "group":"fruits", "icon":"fruis", "coords":[9012,5493], }, { "type":"Food", "name":"Rice", "group":"foods", "icon":"foods", "coords":[6724,9556], }, { "type":"Food", "name":"Meat", "group":"foods", "icon":"foods", "coords":[6724,9556], }, { "type":"Food", "name":"Beam", "group":"foods", "icon":"foods", "coords":[6724,9556], }, { "type":"Liquid", "name":"Water", "group":"liquids", "icon":"liquids", "coords":[6724,9556], }, { "type":"Liquid", "name":"Coffe", "group":"liquids", "icon":"liquids", "coords":[6724,9556], }, ]
    
    const group = data.reduce((r,c) => (r[c.group] = (r[c.group] || 0) + 1, r), {})
    console.log(Object.entries(group).map(([k,v]) => ({ item: k, qnt: v })))
        5
  •  2
  •   brk    6 年前

    var markers = [{
        "type": "Chocolate",
        "name": "KitKat",
        "group": "candy",
        "icon": "candy",
        "coords": [5246, 8980],
      },
      {
        "type": "Fruit",
        "name": "Orange",
        "group": "fruits",
        "icon": "fruis",
        "coords": [9012, 5493],
      },
      {
        "type": "Fruit",
        "name": "Banana",
        "group": "fruits",
        "icon": "fruis",
        "coords": [9012, 5493],
      },
      {
        "type": "Food",
        "name": "Rice",
        "group": "foods",
        "icon": "foods",
        "coords": [6724, 9556],
      },
      {
        "type": "Food",
        "name": "Meat",
        "group": "foods",
        "icon": "foods",
        "coords": [6724, 9556],
      },
      {
        "type": "Food",
        "name": "Beam",
        "group": "foods",
        "icon": "foods",
        "coords": [6724, 9556],
      },
      {
        "type": "Liquid",
        "name": "Water",
        "group": "liquids",
        "icon": "liquids",
        "coords": [6724, 9556],
      },
      {
        "type": "Liquid",
        "name": "Coffe",
        "group": "liquids",
        "icon": "liquids",
        "coords": [6724, 9556],
      },
    ]
    
    
    let count = markers.reduce(function(acc, curr) {
      if (acc[curr.type]) {
        acc[curr.type] += 1;
      } else {
        acc[curr.type] = 1;
      }
    
      return acc;
    }, {})
    
    console.log(count)
    
    /* if you need an array of objects then ,instead of object ,
    pass an empty array as the accumulator. Then in that 
    accumulator search if the type exist using findIndex.
    If it returns -1 then create a new object with 
    required values and push it in the accumulator,
     else update the value of qnt at that specific index*/
    
    let count1 = markers.reduce(function(acc, curr) {
      let getItemIndex = acc.findIndex(function(item) {
        return item.item === curr.group
      });
    
      if (getItemIndex === -1) {
        let obj = {
          item: curr.group,
          qnt: 1
        }
        acc.push(obj)
      } else {
        acc[getItemIndex].qnt += 1;
      }
    
      return acc;
    }, [])
    
    console.log(count1)
        6
  •  2
  •   ibrahim mahrir    6 年前

    在我看来,最好的方法是使用如下格式 { item: count } count 应该是一个对象 {} 而不是数组 [] (见 @brk's answer 计数

    var count = [], cache = {};
    for(var i = 0; i < markers.length; i++) {
      var marker = markers[i];
      if(cache.hasOwnProperty(marker.type)) {           // if the current marker type has already been encountered
        count[cache[marker.type]].qnt++;                // then just retrieve the count object and increment its 'qnt'
      } else {                                          // otherwise
        cache[marker.type] = count.push({               // create a count object for this type and store its index in the cache object
          type: marker.type,
          qnt: 1
        }) - 1;                                         // - 1 because 'push' returns the new array length, thus the index is 'length - 1'
      }
    }
    
        7
  •  1
  •   Django    6 年前
    count = {
      candy: 1
      foods: 3
      fruits: 2
      liquids: 2
    }
    

    从初始数据计算分组计数后,可以将其发送到视图以生成html(它是一个对象,而不是数组)。

    //Add ul
    for(var item in count) {
       //Get data and add li (item = candy, count[item] = 1)
    }
    
        8
  •  1
  •   Max    6 年前

    您可以使用您的代码

    var count = {} // I made an Object out of your Array, the proper way to do this
    
    for (var i = 0; i < markers.length; i++) {
      count[markers[i].group] = count[markers[i].group] + 1 || 1 ;
    }
    

    然后将对象转换为数组:

    var finalArray = [];
    for(var key in count)
      finalArray.push({item: key, qnt: count[key]});
    }
    
        9
  •  1
  •   COLBY BROOKS    6 年前

    var markers = [{"type":"Chocolate","name":"KitKat","group":"candy","icon":"candy","coords":[5246,8980]},{"type":"Fruit","name":"Orange","group":"fruits","icon":"fruis","coords":[9012,5493]},{"type":"Fruit","name":"Banana","group":"fruits","icon":"fruis","coords":[9012,5493]},{"type":"Food","name":"Rice","group":"foods","icon":"foods","coords":[6724,9556]},{"type":"Food","name":"Meat","group":"foods","icon":"foods","coords":[6724,9556]},{"type":"Food","name":"Beam","group":"foods","icon":"foods","coords":[6724,9556]},{"type":"Liquid","name":"Water","group":"liquids","icon":"liquids","coords":[6724,9556]},{"type":"Liquid","name":"Coffe","group":"liquids","icon":"liquids","coords":[6724,9556]}]
    
    counts = []
    markers.map(marker => counts.filter(type => type.name == marker.group).length> 0 ? counts.filter(type=>type.name ==marker.group)[0].count ++ : counts.push({'name':marker.group,'count':1}));
    console.log(counts);

    正如上面有人所说,使用reduce同样有效。