最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arrays - Create Frequency Map Using Map - JavaScript - Stack Overflow

programmeradmin2浏览0评论

Trying to solve this Codwars Kata.

Given an array, find the duplicates in that array, and return a new array of those duplicates. The elements of the returned array should appear in the order when they first appeared as duplicates.

Examples:

[1, 2, 4, 4, 3, 3, 1, 5, 3, '5']  ==>  [4, 3, 1]
[0, 1, 2, 3, 4, 5]                ==>  []

I have:

function duplicates(arr) {

  arr.sort((value, index) => value - index);
  let duplicates = [];
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === arr[i + 1]) {
      duplicates.unshift(arr[i]);
    }
  }
  //filter out duplicates within "duplicates"
  duplicates = duplicates.filter((value, index) =>
     duplicates.indexOf(value) == index);
  return duplicates;
}

console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5'])); 

Trying to solve this Codwars Kata.

Given an array, find the duplicates in that array, and return a new array of those duplicates. The elements of the returned array should appear in the order when they first appeared as duplicates.

Examples:

[1, 2, 4, 4, 3, 3, 1, 5, 3, '5']  ==>  [4, 3, 1]
[0, 1, 2, 3, 4, 5]                ==>  []

I have:

function duplicates(arr) {

  arr.sort((value, index) => value - index);
  let duplicates = [];
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === arr[i + 1]) {
      duplicates.unshift(arr[i]);
    }
  }
  //filter out duplicates within "duplicates"
  duplicates = duplicates.filter((value, index) =>
     duplicates.indexOf(value) == index);
  return duplicates;
}

console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5'])); 

This is passing all tests except for one:

Expected: '[1, 4]', instead got: '[4, 1]'

And I'm not sure why - unfortunately it does not display the test case.

It was suggested that another way to create a frequency map, however, is with Map. How would I do this?

I tried:

function duplicates(arr) {

  let map = new Map([arr]);
  return map;

}

console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5'])); 

and this doesn't create a frequency map.

What other suggestions would you have?

NOTE - "5" and 5 should not count as the same value.

EDIT - Initially, tried to create a frequencyMap like this:

function duplicates(arr) {
  let map = {};
  arr.forEach((value, index) => {
    if (!map[value]) {
      map[value] = 0;
    }
    map[value] += 1;
  })
  return map;
}

console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5'])); 

But in this case, "5" and 5 are considered to be the same value. I don't know how else to check for duplicates - sorting disrupts the order in which the duplicates appear; and creating a frequencyMap count numbers and strings as the same thing.

Share Improve this question edited Jul 8, 2019 at 23:01 HappyHands31 asked Jun 25, 2019 at 23:31 HappyHands31HappyHands31 4,11119 gold badges66 silver badges117 bronze badges 4
  • 1 The instructions say: The elements of the returned array should appear in the order when they first appeared as duplicates. But the first thing you do is throw that information away by sorting the array. – Mark Commented Jun 25, 2019 at 23:34
  • I remember now why I sorted - I had tried to create a frequencyMap, but that counted 5 and "5" as the same thing, which is also against the rules. – HappyHands31 Commented Jun 25, 2019 at 23:44
  • Use a Map instead of an object to keep count. It distinguishes types for keys. – Mark Commented Jun 25, 2019 at 23:59
  • @MarkMeyer right, that's what I'm not understanding - how can I use Map to keep count? – HappyHands31 Commented Jun 26, 2019 at 0:11
Add a ment  | 

2 Answers 2

Reset to default 2

Here's an idea that should work:

Create a Map (map keys distinguish type so 5 is a different key than "5")

Use filter to go through the items in your array. As you go through keep count of how many times you've seen an item in your Map. Return true from the filter only when the count (before you've increased it) is 1. That's the second time you've seen that item.

The filter should return your answer:

function duplicates(arr) {
   let counts = new Map()
   return arr.filter(n => {
        let count = counts.get(n)
        counts.set(n, count ? count+1 : 1)
        return count === 1     
   })
}

console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5'])); 

Might not be the most efficient solution, but it solves the challenge. Note, I'm using js object to mimic a Map

 function duplicates(arr) {
  // TODO: return the array of duplicates from arr
  const map = {};
  const dup = {};

  for (const val of arr) {
    let key = val;
    if (typeof val === 'string') {
      key = `${val}_str`;
    }

    if (map[key]) {
      dup[val] = true;
    } else {
      map[key] = true;
    }
  }
  return Object.keys(dup)
  .map( d => (!Number.isInteger(parseInt(d))) ? d : Number(d));
}

console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5'])); 

发布评论

评论列表(0)

  1. 暂无评论