首页 > 其他分享 >【ES6】使用Set和Map进行全组合判断

【ES6】使用Set和Map进行全组合判断

时间:2024-08-07 18:23:45浏览次数:9  
标签:ES6 Set const valueSet Map fieldMap 字段 key data

判断数据集是否为全组合关系

例如下列表格,字段1包含(甲、乙)值,字段2包含(a、b)值,字段3包含(1、2、3)值,每种组合情况都可以在数据集的行记录中找到有且仅有的一条

字段1字段2字段3
a1
a2
a3
b1
b2
b3
a1
a2
a3
b1
b2
b3

要求函数输入以下格式数据,输出布尔值。

const inputData = [
	{ "字段1": "甲", "字段2": "a", "字段3": 1 },
	{ "字段1": "甲", "字段2": "a", "字段3": 2 },
	{ "字段1": "甲", "字段2": "a", "字段3": 3 },
	{ "字段1": "甲", "字段2": "b", "字段3": 1 },
	{ "字段1": "甲", "字段2": "b", "字段3": 2 },
	{ "字段1": "甲", "字段2": "b", "字段3": 3 },
	{ "字段1": "乙", "字段2": "a", "字段3": 1 },
	{ "字段1": "乙", "字段2": "a", "字段3": 2 },
	{ "字段1": "乙", "字段2": "a", "字段3": 3 },
	{ "字段1": "乙", "字段2": "b", "字段3": 1 },
	{ "字段1": "乙", "字段2": "b", "字段3": 2 },
	{ "字段1": "乙", "字段2": "b", "字段3": 3 },
]

实现

1.遍历inputData并罗列出每个字段对应的全部可能值:

const inputData = [
  { "字段1": "甲", "字段2": "a", "字段3": 1 },
  { "字段1": "甲", "字段2": "a", "字段3": 2 },
  { "字段1": "甲", "字段2": "a", "字段3": 3 },
  { "字段1": "甲", "字段2": "b", "字段3": 1 },
  { "字段1": "甲", "字段2": "b", "字段3": 2 },
  { "字段1": "甲", "字段2": "b", "字段3": 3 },
  { "字段1": "乙", "字段2": "a", "字段3": 1 },
  { "字段1": "乙", "字段2": "a", "字段3": 2 },
  { "字段1": "乙", "字段2": "a", "字段3": 3 },
  { "字段1": "乙", "字段2": "b", "字段3": 1 },
  { "字段1": "乙", "字段2": "b", "字段3": 2 },
  { "字段1": "乙", "字段2": "b", "字段3": 3 },
]

function isFullCombination(data) {
  if (data.length === 0) {
    return false
  }

  const fieldMap = new Map() // 字段映射对象
  const keys = Object.keys(data[0]) // 获取数据集字段名

  for (const item of data) {
    for (const key of keys) {
      const value = item[key]
      let valueSet = fieldMap.get(key) // 尝试获取Map中字段对应的值集合
      if (!valueSet) {
        valueSet = new Set() // 使用Set实现去重
        fieldMap.set(key, valueSet)
      }
      valueSet.add(value)
    }
  }

  console.log(fieldMap);
}

console.log(isFullCombination(inputData));
Map(3) {
  '字段1' => Set(2) { '甲', '乙' },
  '字段2' => Set(2) { 'a', 'b' },
  '字段3' => Set(3) { 1, 2, 3 }
}

2.那么全组合情况下,inputData数组的长度应为 2*2*3,也就是12,对长度进行判断:

function isFullCombination(data) {
  if (data.length === 0) {
    return false
  }

  const fieldMap = new Map()
  const keys = Object.keys(data[0]) 

  for (const item of data) {
    for (const key of keys) {
      const value = item[key]
      let valueSet = fieldMap.get(key) 
      if (!valueSet) {
        valueSet = new Set() 
        fieldMap.set(key, valueSet)
      }
      valueSet.add(value)
    }
  }
  
  const length = [...fieldMap].reduce((s, [, v]) => (s *= v.size), 1)
  return length === data.length // 对比length
}

3.除了length还需要考虑元素是否重复,如果对inputData进行去重处理,会提高时间复杂度,所以在已有的循环中顺便进行是否重复的判断即可。将所有值拼接为字符串并存储到集合中,对比字符串是否相同。

注意:拼接后的字符存储到集合中,因为需要判断集合中是否已有重复的字符串,所以使用Set存储,因为Set.has时间复杂度为O(1),而Array判断时间复杂度为O(n)。

function isFullCombination(data) {
  if (data.length === 0) {
    return false
  }

  const fieldMap = new Map() 
  const keys = Object.keys(data[0]) 

  const combinationSet = new Set() // 组合情况集合
  for (const item of data) {
    let combination = ""
    for (const key of keys) {
      const value = item[key]
      let valueSet = fieldMap.get(key) 
      if (!valueSet) {
        valueSet = new Set() 
        fieldMap.set(key, valueSet)
      }
      valueSet.add(value)
      combination += value
    }
    if (combinationSet.has(combination)) {
      return false // 如果重复,则说明不是全组合
    }
    combinationSet.add(combination) // 如果不存在,则添加到集合中
  }
  console.log(combinationSet)

  const length = [...fieldMap].reduce((s, [, v]) => (s *= v.size), 1)
  return length === data.length
}

4.但是还存在问题,那就是字段值重复,如下面这个inputData:

const inputData = [
  { a: "-", b: "-" },
  { a: "-", b: "--" },
  { a: "--", b: "-" },
  { a: "--", b: "--" },
]

目前无法判断,需要在存入映射对象时手动将值存为唯一值,这里通过自增的n作为唯一标识,然后使用每个字段对应的唯一标识拼接字符串。

function isFullCombination(data) {
  if (data.length === 0) {
    return false
  }

  const fieldMap = new Map() 
  const keys = Object.keys(data[0]) 
  const combinationSet = new Set()
  const valueMap = new Map() // 记录每个字段的值集合
  let n = 1

  for (const item of data) {
    let combination = ""
    for (const key of keys) {
      const value = item[key]
      let valueSet = fieldMap.get(key)
      if (!valueSet) {
        valueSet = new Set() 
        fieldMap.set(key, valueSet)
      }
      valueSet.add(value)

      let num = valueMap.get(value) // 尝试获取Map中字段对应的值
      if (!num) {
        num = n++
        valueMap.set(value, num) 
      }
      combination += num+''
    }
    console.log(valueMap)

    if (combinationSet.has(combination)) {
      return false 
    }
    combinationSet.add(combination) 
  }

  const length = [...fieldMap].reduce((s, [, v]) => (s *= v.size), 1)
  return length === data.length
}

整体实现代码

const inputData = [
  { 字段1: "甲", 字段2: "a", 字段3: 1 },
  { 字段1: "甲", 字段2: "a", 字段3: 2 },
  { 字段1: "甲", 字段2: "a", 字段3: 3 },
  { 字段1: "甲", 字段2: "b", 字段3: 1 },
  { 字段1: "甲", 字段2: "b", 字段3: 2 },
  { 字段1: "甲", 字段2: "b", 字段3: 3 },
  { 字段1: "乙", 字段2: "a", 字段3: 1 },
  { 字段1: "乙", 字段2: "a", 字段3: 2 },
  { 字段1: "乙", 字段2: "a", 字段3: 3 },
  { 字段1: "乙", 字段2: "b", 字段3: 1 },
  { 字段1: "乙", 字段2: "b", 字段3: 2 },
  { 字段1: "乙", 字段2: "b", 字段3: 3 },
]

// const inputData = [
//   { a: "-", b: "-" },
//   { a: "-", b: "--" },
//   { a: "--", b: "-" },
//   { a: "--", b: "--" },
// ]

function isFullCombination(data) {
  if (data.length === 0) {
    return false
  }

  const fieldMap = new Map() // 字段映射对象
  const keys = Object.keys(data[0]) // 获取数据集字段名
  const combinationSet = new Set() // 组合情况集合
  const valueMap = new Map() // 记录每个字段的值集合
  let n = 1

  for (const item of data) {
    let combination = ""
    for (const key of keys) {
      const value = item[key]
      let valueSet = fieldMap.get(key) // 尝试获取Map中字段对应的值集合
      if (!valueSet) {
        valueSet = new Set() // 使用Set实现去重
        fieldMap.set(key, valueSet)
      }
      valueSet.add(value)

      let num = valueMap.get(value) // 尝试获取Map中字段对应的值
      if (!num) {
        num = n++
        valueMap.set(value, num)
      }
      combination += num + ""
    }
    console.log(combination)

    if (combinationSet.has(combination)) {
      return false // 如果重复,则说明不是全组合
    }
    combinationSet.add(combination) // 如果不存在,则添加到集合中
  }

  const length = [...fieldMap].reduce((s, [, v]) => (s *= v.size), 1)
  return length === data.length
}

console.log(isFullCombination(inputData))

标签:ES6,Set,const,valueSet,Map,fieldMap,字段,key,data
From: https://blog.csdn.net/owo_ovo/article/details/140987084

相关文章

  • 深入探讨swr_alloc_set_opts2
    FFmpeg是一个强大的多媒体处理工具,提供了广泛的功能用于处理音视频数据。在音频处理过程中,重采样是一个常见且重要的操作。FFmpeg提供了一个名为swr_alloc_set_opts2的函数,用于配置音频重采样的参数。什么是音频重采样?音频重采样(Resampling)是将音频数据从一个采样率转换......
  • mapboxgl 加载瓦片网格
    importmapboxglfrom"mapbox-gl";exportdefaultclassGridLayer{constructor(map){this.map=map;this.gridSourceId="grid-source";this.gridLayerId="grid-layer";this.labelSourceId="label-sour......
  • 定时器为什么最好不要使用 setInterval()?
    论题setInterval()会导致导致定时器"重叠"的问题,所以使用setTimeout()。回顾首先先了解一下setInterval()和setTimeout()的基本使用。setTimeout(表达式,毫秒):毫秒数后表达式仅执行一次。setInterval(表达式,毫秒):无限次在毫秒数后执行表达式。一个生产者-临界资源问题......
  • [转]相同CRC不同数据的测试.CRC16 - CRC64 test results on 18.2M dataset
    转载自: http://www.backplane.com/matt/crc64.html  CRC16-CRC64testresultson18.2Mdataset,w/programsourceProgram&TestRunbyMattDillon18.2Mmessage-iddatasetsuppliedbyJoeGrecoIwouldliketothankeveryonewhoofferedtheirhistoryf......
  • 神经网络中的评价指标:混淆矩阵、Acc, Precision, Recall, F1分数、[email protected][email protected]:0
    混淆矩阵(ConfusionMatrix)是一个常用的分类模型性能评价工具,用于可视化分类算法的性能表现。混淆矩阵以矩阵的形式展示了分类模型的预测结果与真实结果之间的各种组合情况。混淆矩阵通常是一个2x2的矩阵,如果是二分类问题的话。矩阵的行代表真实的类别,列代表预测的类别。矩......
  • 4.3 ES6 Class 类
    4.3ES6Class类分类 ES6教程概述在ES6中,class(类)作为对象的模板被引入,可以通过class关键字定义类。class的本质是function。它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法。基础用法类定义类表达式可以为匿名或命名。//匿名......
  • 如何解决hashmap不按序问题
    HashMap 在Java中本质上是不保证任何顺序的,特别是它不保证元素会按照插入的顺序进行存储或遍历。如果需要维护元素的插入顺序,可以使用 LinkedHashMap,它在内部通过维护一个双向链表来保持插入顺序。如果想要按照键的自然顺序或者自定义的比较器顺序来存储和遍历键值对,可以使......
  • @MapperScan的作用,以及与@Mapper的区别
    @MapperScan的作用@MapperScan的作用:这个注解告诉MyBatis-Spring-Boot-Starter自动扫描指定包(及其子包)下的所有接口。对于扫描到的每个接口,MyBatis会自动创建一个MapperFactoryBean。这个MapperFactoryBean会被注册到Spring容器中。自动IoC管理:通过上述过......
  • 【题解】Solution Set - NOIP2024集训Day1 数据结构
    【题解】SolutionSet-NOIP2024集训Day1数据结构https://www.becoder.com.cn/contest/5429「CF1428F」FruitSequences线段树是可以维护区间最长子段的1。记固定右端点在\(i\),的答案为\(f_i\)。那么:\(a_i=0\),\(f_i=f_{i-1}\);\(a_i=1\),打一个单调栈维护所有的最长子......
  • Hadoop3.4.0跑wordcount程序报错:org.apache.hadoop.mapreduce.v2.app.MRAppMaster
    部署完Hadoop3.4.0HA后跑wordcount程序报错,在日志文件里 http://rsnode:8042/logs/userlogs 里看到报错日志说不能加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster网上给的办法大多都是让执行hadoopclasspath然后把那一长串配置到 mapred-site.xml。如图 ......