如何确保生成1万份带随机元数据的JSON文件无完全重复参数组合
实现方案
首先先修正你给出的extraMetadata代码的笔误:IQ对应的字段键名写为了vvalue,需要改为value,否则该属性无法正常取值。
你的7个属性每个的取值范围都是0-49共50种可能,总组合数为507=7.8125×1011,远大于你需要的10000个,完全不存在组合耗尽的问题,重试逻辑的性能开销可以忽略。
核心去重逻辑思路
- 用内存哈希集合存储已经生成过的组合唯一标识,判断重复的时间复杂度为O(1),性能极高
- 每个组合按固定属性顺序拼接值为字符串作为唯一键,比如按
Stamina,Strength,Aggressiveness,IQ,Bravery,Nerdy,Coolness的顺序拼接成类似12,3,47,22,9,41,33的字符串,避免因为数组顺序变化导致的误判 - 每次生成新的属性组合后先计算唯一键,判断是否在哈希集合中,存在就重新生成,不存在就存入集合后再写入JSON文件
JS 环境实现代码(匹配你给出的JS语法代码)
首先是修正后的属性生成方法:
const extraMetadata = () => ([ { display_type: "boost_number", trait_type: "Stamina", value: Math.floor(Math.random() * 50), }, { display_type: "boost_number", trait_type: "Strength", value: Math.floor(Math.random() * 50), }, { display_type: "boost_number", trait_type: "Aggressiveness", value: Math.floor(Math.random() * 50), }, { display_type: "boost_number", trait_type: "IQ", value: Math.floor(Math.random() * 50), // 修正笔误 }, { display_type: "boost_number", trait_type: "Bravery", value: Math.floor(Math.random() * 50), }, { display_type: "boost_number", trait_type: "Nerdy", value: Math.floor(Math.random() * 50), }, { display_type: "boost_number", trait_type: "Coolness", value: Math.floor(Math.random() * 50), }, ]);
批量生成去重JSON文件的完整逻辑:
const fs = require('fs'); const path = require('path'); const USED_COMBINATIONS = new Set(); const TOTAL_COUNT = 10000; const OUTPUT_PATH = './metadata_output'; // 固定属性顺序,保证唯一键生成逻辑稳定 const TRAIT_ORDER = ['Stamina', 'Strength', 'Aggressiveness', 'IQ', 'Bravery', 'Nerdy', 'Coolness']; // 创建输出目录 if (!fs.existsSync(OUTPUT_PATH)) fs.mkdirSync(OUTPUT_PATH, { recursive: true }); // 生成唯一键 const getUniqueKey = (metaList) => { return TRAIT_ORDER.map(trait => metaList.find(item => item.trait_type === trait).value).join(','); } // 生成不重复的属性组合 const getUniqueMeta = () => { let meta, key; do { meta = extraMetadata(); key = getUniqueKey(meta); } while (USED_COMBINATIONS.has(key)); USED_COMBINATIONS.add(key); return meta; } // 批量生成文件 for (let i = 0; i < TOTAL_COUNT; i++) { const uniqueMeta = getUniqueMeta(); // 替换为你自己的attributesList const attributesList = []; const fileContent = { attributes: [...attributesList, ...uniqueMeta] // 其他JSON字段可以在这里补充 }; fs.writeFileSync( path.join(OUTPUT_PATH, `${i + 1}.json`), JSON.stringify(fileContent, null, 2) ); }
Java 环境实现代码
如果确实是Java环境,核心逻辑和JS一致,用HashSet存储已生成的键即可,核心代码示例:
import com.alibaba.fastjson2.JSON; import java.io.FileWriter; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Random; public class MetaGenerator { private static final int TOTAL = 10000; private static final Random RANDOM = new Random(); private static final HashSet<String> USED_KEYS = new HashSet<>(); private static final String[] TRAITS = {"Stamina", "Strength", "Aggressiveness", "IQ", "Bravery", "Nerdy", "Coolness"}; static class MetaItem { public String display_type = "boost_number"; public String trait_type; public int value; public MetaItem(String trait_type, int value) { this.trait_type = trait_type; this.value = value; } } private static String generateKey(int[] values) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < values.length; i++) { if (i > 0) sb.append(","); sb.append(values[i]); } return sb.toString(); } private static List<MetaItem> generateUniqueMeta() { int[] values; String key; do { values = new int[7]; for (int i = 0; i < 7; i++) values[i] = RANDOM.nextInt(50); key = generateKey(values); } while (USED_KEYS.contains(key)); USED_KEYS.add(key); List<MetaItem> list = new ArrayList<>(); for (int i = 0; i < 7; i++) list.add(new MetaItem(TRAITS[i], values[i])); return list; } public static void main(String[] args) throws Exception { for (int i = 0; i < TOTAL; i++) { List<MetaItem> uniqueMeta = generateUniqueMeta(); // 组装你自己的attributesList、生成JSON写入文件即可 String json = JSON.toJSONString(uniqueMeta); try (FileWriter writer = new FileWriter("./output/" + (i+1) + ".json")) { writer.write(json); } } } }
内容的提问来源于stack exchange,提问作者HumMing birD
相关产品推荐
相关产品推荐

