admin管理员组

文章数量:1023758

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'])); 

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'])); 

本文标签: arraysCreate Frequency Map Using MapJavaScriptStack Overflow