Fetch the no of of occurence in a array based on other key value

天涯浪子 提交于 2020-01-03 04:50:14

问题


var json = [{
        "city": "California",
        "name": "Joe",
        "age": 17,
        "type",:"custom"
    }, {
        "city": "California",
        "name": "Bob",
        "age": 17,
        "type",:"predefined"
    }, {
        "city": "California",
        "name": "Bob",
        "age": 35,
        "type",:"custom"
    }, {
        "city": "Texas",
        "name": "Bob",
        "age": 35,
        "type",:"custom"
    }, {
        "city": "Florida",
        "name": "Bob",
        "age": 35,
        "type",:"predefined"
 }];

I have above array and i have to construct object, based on "type" value i.e "predefined" or "custom" as below

updatedjson = {
    "predefined": [{
            "name": "California",
            "count": 1
        }, {
            "name": "Florida",
            "count": 1
        }]
     "custom": [{
            "name": "California",
            "count": 2
        }, {
            "name": "Texas",
            "count": 1
        }]
 }

Any Approach using javascript or lodash


回答1:


Using Lodash

var json = [{
  "city": "California",
  "name": "Joe",
  "age": 17,
  "type": "custom"
}, {
  "city": "California",
  "name": "Bob",
  "age": 17,
  "type": "predefined"
}, {
  "city": "California",
  "name": "Bob",
  "age": 35,
  "type": "custom"
}, {
  "city": "Texas",
  "name": "Bob",
  "age": 35,
  "type": "custom"
}, {
  "city": "Florida",
  "name": "Bob",
  "age": 35,
  "type": "predefined"
}];

// Solution to the problem

var updatedJson = _(json).groupBy("type").value();    // #1

_.forOwn(updatedJson, function(value, key) {
  let countByCity = _(value).countBy('city').value(); // #2
  let res = [];

  _.forOwn(countByCity, function(value, key) {
    res.push({                                        // #3
      name: key,
      count: value
    });
  });

  updatedJson[key] = res;
});

console.log(updatedJson);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

Explanation

  1. Code first groups by type
  2. Then counts by cities, within the group
  3. Finally pushes the count object into an array, in the expected format



回答2:


You can use reduce & findIndex

var json = [{
  "city": "California",
  "name": "Joe",
  "age": 17,
  "type": "custom"
}, {
  "city": "California",
  "name": "Bob",
  "age": 17,
  "type": "predefined"
}, {
  "city": "California",
  "name": "Bob",
  "age": 35,
  "type": "custom"
}, {
  "city": "Texas",
  "name": "Bob",
  "age": 35,
  "type": "custom"
}, {
  "city": "Florida",
  "name": "Bob",
  "age": 35,
  "type": "predefined"
}];

var updatedjson = json.reduce(function(result, item) {
  // check if type is present in the object
  // if not present then add a key by name custom/predefined
  if (!result[item.type]) {
    result[item.type] = [];
    // add city name and intial count
    result[item.type].push({
      name: item.city,
      count: 1
    })
  } else {
    // now find the index of the object whe name matches with current city
    let m = result[item.type].findIndex(function(obj) {
      return obj.name === item.city
    })
    // if no matches then add the new object to either custom/predefined
    if (m === -1) {
      result[item.type].push({
        name: item.city,
        count: 1
      })
    } else {
      // if matches then increase the value of count
      result[item.type][m].count += 1
    }

  }
  return result;

}, {});

console.log(updatedjson)



回答3:


You can use array.reduce to create a new object with the aggregated data. Example:

  const result = json.reduce((obj, data) => {
      // if this is a new type, we must initialize it as an empty array and push the first record.
      if(!obj[data.type]) {
        obj[data.type] = [];
        obj[data.type].push({name: data.city, count: 1});
        return obj;
      }
      // else ... check if the current city is present in that type
      const existingRecord = obj[data.type].find(d => d.name === data.city);
      if(!existingRecord) {
         // if the city is not present in that type, we initialize it with count 1
         obj[data.type].push({name: data.city, count: 1});
         return obj;
      }
      // if the city is present, we just update count = count + 1;
      existingRecord.count++;
      return obj;
    }, { })

Now, you probably want to extract some of that logic into separate functions to increase readability. I don't think you need lodash for this but in the case you already have it included in your project then feel free to use it :P



来源:https://stackoverflow.com/questions/49055027/fetch-the-no-of-of-occurence-in-a-array-based-on-other-key-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!