使用地图创建频率图-JavaScript

时间:2019-06-25 23:31:26

标签: javascript arrays object frequency

尝试解决此Codwars Kata

  

给出一个数组,找到该数组中的重复项,然后返回这些重复项的新数组。返回数组的元素首次出现时应按顺序出现。

示例:

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

我有:

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

这将通过除一项以外的所有测试:

  

期望:'[1,4]',而不是:'[4,1]'

我不确定为什么-不幸的是,它没有显示测试用例。

有人建议创建频率图的另一种方法是使用Map。我该怎么做?

我尝试过:

function duplicates(arr) {

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

}

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

,这不会创建频率图。

您还有其他建议吗?

注意-“ 5”和5不应视为相同的值。

编辑-最初,尝试创建如下的frequencyMap:

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

但是在这种情况下,“ 5”和5被认为是相同的值。我不知道该如何检查重复项-排序会破坏重复项出现的顺序;并同时创建一个frequencyMap计数数字和字符串。

3 个答案:

答案 0 :(得分:2)

这是一个可行的想法:

创建一个Map(映射键区分类型,因此5是与"5"不同的键)

使用过滤器浏览数组中的项目。在浏览过程中,请计算您在地图中看到过多少次。仅当计数(在增加之前)为true时,才从过滤器返回1。这是您第二次看到该物品。

过滤器应返回您的答案:

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

答案 1 :(得分:1)

可能不是最有效的解决方案,但它可以解决挑战。请注意,我正在使用js object来模仿地图

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

答案 2 :(得分:1)

让我们假设我的响应是对象数组:-

enter image description here

assessment_type: (13) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, { …}、{…}、{…}] 展开后你得到以下

解决方案:

  const [assessmentType, setassessmentType] = useState([]);
  let assessmentCountMap = new Map();

  setassessmentType(response.data.body["assessment_type"]);

  assessmentType.forEach((obj) => {
      assessmentCountMap.set(
        obj["assessment_type"],
        (assessmentCountMap.get(obj["assessment_type"]) || 0) + 1
      );
    });

enter image description here