-2

how to count the value of object in new object values lets say that i have json like this :

let data = [{
    no: 3,
    name: 'drink'
  },
  {
    no: 90,
    name: 'eat'
  },
  {
    no: 20,
    name: 'swim'
  }
];

if i have the user pick no in arrays : [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]

so the output should be an array

[
 { 
   num: 3,
   total: 11
 },
 {
   num: 90,
   total: 1
 },
 {
   num:20,
   total: 4
 }

];

I would like to know how to do this with a for/of loop

Here is the code I've attempted:

let obj = [];
for (i of arr){
  for (j of data){
    let innerObj={};
    innerObj.num = i
    obj.push(innerObj)
  } 
}
Andy
  • 61,948
  • 13
  • 68
  • 95
Zum Dummi
  • 243
  • 1
  • 11

3 Answers3

1

const data = [{"no":3,"name":"drink"},{"no":90,"name":"eat"},{"no":20,"name":"swim"}];
const arr = [3,3,3,3,3,3,3,3,3,3,3,20,20,20,20,80,80];
const lookup = {};

// Loop over the duplicate array and create an
// object that contains the totals
for (let el of arr) {

  // If the key doesn't exist set it to zero,
  // otherwise add 1 to it
  lookup[el] = (lookup[el] || 0) + 1;  
}

const out = [];
// Then loop over the data updating the objects
// with the totals found in the lookup object
for (let obj of data) {
  lookup[obj.no] && out.push({
    no: obj.no,
    total: lookup[obj.no]
  });
}

document.querySelector('#lookup').textContent = JSON.stringify(lookup, null, 2);
document.querySelector('#out').textContent = JSON.stringify(out, null, 2);
<h3>Lookup output</h3>
<pre id="lookup"></pre>

<h3>Main output</h3>
<pre id="out"></pre>
Andy
  • 61,948
  • 13
  • 68
  • 95
0

Perhaps something like this? You can map the existing data array and attach filtered array counts to each array object.

let data = [
  {
    no: 3,
    name: 'drink'
  },
  {
    no:90,
    name: 'eat'
  },
  {
    no:20,
    name: 'swim'
  }
]

const test = [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]

const result = data.map((item) => {
  return {
    num: item.no,
    total: test.filter(i => i === item.no).length // filters number array and then checks length
  }
})
cesar
  • 43
  • 1
  • 8
  • how about if we use `for of` ?? – Zum Dummi Jan 18 '19 at 16:54
  • If you haven't done the work yourself, and are asking for help, it's pretty bold to then be opinionated about the code you're then given. – Andy Jan 18 '19 at 16:58
  • You could do this but I don't see why you'd prefer this `const arr = [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]; let result = []; for (let item of data) { const obj = { num: item.no, total: arr.filter(i => i === item.no).length } result.push(obj); }` – cesar Jan 18 '19 at 17:09
  • how about if the test array jus show 2 numbers from that object, we should not add the numbers which not show in the arrays – Zum Dummi Jan 18 '19 at 17:11
  • Just check for the filtered array length before pushing the object to the array. – cesar Jan 18 '19 at 17:15
0

You can check next approach using a single for/of loop. But first I have to create a Set with valid ids, so I can discard noise data from the test array:

const data = [
    {no: 3, name: 'drink'},
    {no: 90, name: 'eat'},
    {no: 20, name: 'swim'}
];

const userArr = [3,3,3,3,3,3,3,3,7,7,9,9,3,3,3,90,20,20,20,20];

let ids = new Set(data.map(x => x.no));
let newArr = [];

for (i of userArr)
{
   let found = newArr.findIndex(x => x.num === i)

   if (found >= 0)
       newArr[found].total += 1;
   else
       ids.has(i) && newArr.push({num: i, total: 1});
}

console.log(newArr);
Shidersz
  • 16,846
  • 2
  • 23
  • 48