0

What's the best way to get duplicates in an array of hashes with strings and count number of appearances.

If I have this array of hashes

const data = [
  {
    url: 'https://app.mywebsite.net/endpoint1',
    method: 'POST'
  },
  {
    url: 'https://app.mywebsite.net/endpoint2',
    method: 'POST'
  },
  {
    url: 'https://app.mywebsite.net/endpoint1',
    method: 'POST'
  }
]

And I want to get the hashes that are duplicated and the amount of times they appear like

 {
    url: 'https://app.mywebsite.net/endpoint1',
    method: 'POST',
    count: 2
  }, 
  {
    url: 'https://app.mywebsite.net/endpoint2',
    method: 'POST',
    count: 1
  },

Javascript - Counting duplicates in object array and storing the count as a new object

6
  • 2
    What problem are you having with the answers in the link to the other question? The chosen answer in that question should be what you follow to get your answer. Commented Feb 11, 2020 at 15:42
  • if you try the answer on the question, only returns 1 line with the count of all the lines Commented Feb 11, 2020 at 15:54
  • reading through the code it actually does return an array and not a single value. I verified by copying the code and using your data and it returns exactly what you are asking for. Commented Feb 11, 2020 at 15:58
  • testes this one ? const result = [...names.reduce( (mp, o) => { const key = JSON.stringify([o.cat, o.sub]); if (!mp.has(key)) mp.set(key, { ...o, count: 0 }); mp.get(key).count++; return mp; }, new Map).values()]; and dont works Commented Feb 11, 2020 at 16:03
  • Yeah. You can change names.reduce to data.reduce and [o.cat, o.sub] to [o.url, o.method]. Commented Feb 11, 2020 at 16:05

3 Answers 3

3

You can use Array.reduce for that :

const data = [
  {
    url: "https://app.mywebsite.net/endpoint1",
    method: "POST"
  },
  {
    url: "https://app.mywebsite.net/endpoint2",
    method: "POST"
  },
  {
    url: "https://app.mywebsite.net/endpoint1",
    method: "POST"
  }
];

const result = data.reduce((all, curr) => {
  const ndx = all.findIndex(e => e.url === curr.url);

  if (ndx > -1) {
    all[ndx].count += 1;
  } else {
    all.push({ url: curr.url, count: 1 });
  }

  return all;
}, []);


console.log(result)

Sign up to request clarification or add additional context in comments.

2 Comments

Almost! , is there a way to match all the keys of the hash and return all the hash info ?
@nonyck not sure i follow, can you add a sample of desired results please ?
0

Like @Taki mentions, you can use the Array.prototype.reduce() method.

const frequencies = arr =>
  Object.values(
    arr.reduce((obj, { url, method }) => {
      obj[url] = obj[url] || { url, method, count: 0 }
      obj[url].count += 1
      return obj
    }, {})
  )

const data = [
  {
    url: 'https://app.mywebsite.net/endpoint1',
    method: 'POST',
  },
  {
    url: 'https://app.mywebsite.net/endpoint2',
    method: 'POST',
  },
  {
    url: 'https://app.mywebsite.net/endpoint1',
    method: 'POST',
  },
]

const result = frequencies(data)

console.log(result)

Comments

0

Using with reduce (or forEach) will simplify.

const data = [
  {
    url: "https://app.mywebsite.net/endpoint1",
    method: "POST"
  },
  {
    url: "https://app.mywebsite.net/endpoint2",
    method: "POST"
  },
  {
    url: "https://app.mywebsite.net/endpoint1",
    method: "POST"
  }
];

const updated = data.reduce(
  (acc, curr) =>
    Object.assign(acc, {
      [curr.url]:
        curr.url in acc
          ? { ...acc[curr.url], count: acc[curr.url].count + 1 }
          : { ...curr, count: 1 }
    }),
  {}
);

console.log(updated);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.