Loop through array for each value from another array

How can I loop through this array:

const counts = [
  "900,google.com",
  "60,mail.yahoo.com",
  "10,mobile.sports.yahoo.com",
  "40,sports.yahoo.com",
  "300,yahoo.com",
  "10,stackoverflow.com",
  "20,overflow.com",
  "5,com.com",
  "2,en.wikipedia.org",
  "1,m.wikipedia.org",
  "1,mobile.sports",
  "1,google.co.uk",
];

taking each value from this array?

const uniqueDomains = [
  'google.com',
  'com',
  'mail.yahoo.com',
  'yahoo.com',
  'mobile.sports.yahoo.com',
  'sports.yahoo.com',
  'stackoverflow.com',
  'overflow.com',
  'com.com',
  'en.wikipedia.org',
  'wikipedia.org',
  'org',
  'm.wikipedia.org',
  'mobile.sports',
  'sports',
  'google.co.uk',
  'co.uk',
  'uk'
]

I need to find out if string from counts array includes string from uniqueDomains array. Then push it to the empty object as a key value pairs, where value is going to be the number in the beginning of the each string from counts array.

I tried this code but it give me wrong result in my object’s values(since I am looping twice) I need kind of avoid looping twice, but I am not sure how.

Example com is mentioned 8 time in counts array, which means result should be this {com: 1345}

Here is my code:

const finalObject = {}
uniqueDomains.forEach((dom) => {
  counts.forEach((cnt) => {
    if (cnt.includes(dom)) {
      const num = parseInt(cnt);
      sumArr.push(num);
      const res = sumArr.reduce((acc, cur) => {
        return acc + cur;
      });
      finalObject[dom] = res;
    }
  });
});

Answer

Theres not really any avoiding looping twice (at least), but you can certainly make your code a bit easieer by first turning the count array into an array of val & domain separately.

const countIdx = counts.map(x => {
   const [val,domain] = x.split(",");
   return {val:parseInt(val,10), domain}
});

Then its just a case of looping the uniqueDomain array and finding all the domaion which match and summing up the val

const result = uniqueDomains.reduce( (res, d) => {
    const count = countIdx.filter(x => x.domain.includes(d)).reduce( (acc,x) => acc + x.val,0);
    return {...res, [d]:count}
},{});

Live example follows:

const counts = [
  "900,google.com",
  "60,mail.yahoo.com",
  "10,mobile.sports.yahoo.com",
  "40,sports.yahoo.com",
  "300,yahoo.com",
  "10,stackoverflow.com",
  "20,overflow.com",
  "5,com.com",
  "2,en.wikipedia.org",
  "1,m.wikipedia.org",
  "1,mobile.sports",
  "1,google.co.uk",
];

const uniqueDomains = [
  'google.com',
  'com',
  'mail.yahoo.com',
  'yahoo.com',
  'mobile.sports.yahoo.com',
  'sports.yahoo.com',
  'stackoverflow.com',
  'overflow.com',
  'com.com',
  'en.wikipedia.org',
  'wikipedia.org',
  'org',
  'm.wikipedia.org',
  'mobile.sports',
  'sports',
  'google.co.uk',
  'co.uk',
  'uk'
]

const countIdx = counts.map(x => {
   const [val,domain] = x.split(",");
   return {val:parseInt(val,10), domain}
});

const result = uniqueDomains.reduce( (res, d) => {
    const count = countIdx.filter(x => x.domain.includes(d)).reduce( (acc,x) => acc + x.val,0);
    return {...res, [d]:count}
},{});

console.log(result);