如何根据具有代表性的记录和 属性 特定的生成器函数随机模拟记录数组?
How to randomly simulate an array of records based on a representative record and property-specific generator functions?
给定一条记录的结构,如何随机模拟n条相同结构的记录?
例子
假设我有一个记录数组,例如:
[
{
"id": 12345,
"createdAt": "2021-12-25",
"data": {
"age": {"value": 25},
"height": {"value": 100},
"weight": {"value": 160},
"n_of_kids": {"value": 0},
"fam_status": {"value": "married"},
"preferred_pet": {"value": "dog"},
"preferred_color": {"value": "purple"},
"preferred_movie": {"value": "titanic"}
}
},
{...} // another record
]
我的任务:我想模拟一个n条记录的数组,与上面的结构相同
注意。我特别想找到一个适用于任何给定结构的解决方案。因此,虽然我知道这里给出的结构是次优的(例如,冗余 value
属性 并没有增加太多),但我仍然希望能够解释任何可能的给定结构.
我可以解决这个问题的一种方法是创建一个对象,其 值 是指定每个值应该是什么的正则表达式。
const structureTemplateRegex = {
id: "^[0-9]{5}$", // 5-digit number
createdAt: /^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$/, // yyyy-mm-dd
data: {
age: { value: "/^(?:[0-9]|[1-9][0-9]|100)$/" }, // 0-100
height: { value: "/^(?:1[0-9]|[2-9][0-9]|1[0-9]{2}|2[01][0-9]|220)$/" }, // 10-220
weight: { value: '/^(?:3[0-9]|[4-9][0-9]|[12][0-9]{2}|300)$/' }, // 30-300
n_of_kids: { value: '/^(0|[1-9][0-9]?|7)$/' }, // 0-7
fam_status: { value: '/^(married|single|divorced|widowed)$/' },
preferred_pet: { value: '/^(dog|cat|hamster|fish|rabbit|zebra)$/' },
preferred_color: { value: '/^(red|green|yellow|black|orange|blue)$/' },
preferred_movie: {
value: '/^(titanic|alien|se7en|batman|goodfellas|argo)$/',
},
},
};
嗯,structureTemplateRegex
可能适合验证,但不适合生成数据。所以另一种解决问题的方法是为记录中的每个 属性 编写一个生成器函数。
const generateId = (n = 5) => [...Array(n)].map(_=>Math.random()*10|0).join`` //
const generateDate = (start = new Date(2018, 8, 9), end = new Date(2021, 12, 15)) => new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toISOString().slice(0,10); //
const randomInteger = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; //
const randomElement = (arr) => arr[(Math.random() * arr.length) | 0] //
const generateFamStatus = () => randomElement(["married", "single", "divorced", "widowed"])
const generatePet = () => randomElement(["dog", "cat", "hamster", "fish", "rabbit", "zebra"])
const generateColor = () => randomElement(["red", "green", "yellow", "black", "orange", "blue"])
const generateMovie = () => randomElement(["titanic", "alien", "se7en", "batman", "goodfellas", "argo"])
// and then
const structureTemplateGenerators = {
id: generateId(), // 5-digit number
createdAt: generateDate(), // yyyy-mm-dd
data: {
age: { value: randomInteger(0, 101) }, // 0-100
height: { value: randomInteger(10, 221) }, // 10-220
weight: { value: randomInteger(30, 301) }, // 30-300
n_of_kids: { value: randomInteger(0, 8) }, // 0-7
fam_status: { value: generateFamStatus() },
preferred_pet: { value: generatePet() },
preferred_color: { value: generateColor() },
preferred_movie: {
value: generateMovie(),
},
},
};
但我不太确定如何沿着这条路走下去。我有我需要的材料,但没有技术。本质上,我想要的是调用一个函数,该函数将以下参数作为参数:(1) 一个代表性记录的结构,以及 (2) n
要模拟的记录数。该函数将 return 一个长度为 n
的数组,其中包含随机生成的记录。
// pseudocode
generateRecords(structureTemplateGenerators, 5) // but `n` could potentially be 10 or 10000 or 3e7
// would return
const possibleOutput = [
{
id: 12045,
createdAt: '2021-02-21',
data: {
age: { value: 15 },
height: { value: 80 },
weight: { value: 100 },
n_of_kids: { value: 1 },
fam_status: { value: 'widowed' },
preferred_pet: { value: 'dog' },
preferred_color: { value: 'purple' },
preferred_movie: { value: 'se7en' },
},
},
{
id: 39847,
createdAt: '2020-12-02',
data: {
age: { value: 33 },
height: { value: 56 },
weight: { value: 210 },
n_of_kids: { value: 3 },
fam_status: { value: 'married' },
preferred_pet: { value: 'zebra' },
preferred_color: { value: 'blue' },
preferred_movie: { value: 'argo' },
},
},
{
id: 22435,
createdAt: '2018-10-10',
data: {
age: { value: 25 },
height: { value: 103 },
weight: { value: 165 },
n_of_kids: { value: 5 },
fam_status: { value: 'married' },
preferred_pet: { value: 'dog' },
preferred_color: { value: 'green' },
preferred_movie: { value: 'titanic' },
},
},
{
id: 61194,
createdAt: '2019-04-10',
data: {
age: { value: 20 },
height: { value: 90 },
weight: { value: 100 },
n_of_kids: { value: 3 },
fam_status: { value: 'divorced' },
preferred_pet: { value: 'hamster' },
preferred_color: { value: 'blue' },
preferred_movie: { value: 'batman' },
},
},
{
id: 22231,
createdAt: '2021-10-01',
data: {
age: { value: 77 },
height: { value: 160 },
weight: { value: 69 },
n_of_kids: { value: 1 },
fam_status: { value: 'divorced' },
preferred_pet: { value: 'dog' },
preferred_color: { value: 'red' },
preferred_movie: { value: 'titanic' },
},
},
];
更多上下文
我有一个 JavaScript 应用程序,它接受一组记录并对这些数据进行大量聚合计算。最终,应用程序 return 的输出类似于 JSON
。知道输入记录的结构,我想模拟,随机,一个包含n条记录的数组.这样的程序将允许我在 (1) 计算可靠性和 (2) 速度(随着 n 增加)方面测试我的应用程序。
structureTemplateGenerators 应该是 returns 一个新生成的数据结构的函数。现在,它只是创建一个已经设置了值的结构。
const structureTemplateGenerators = () => ({
id: generateId(), // 5-digit number
createdAt: generateDate(), // yyyy-mm-dd
data: {
age: { value: randomInteger(0, 101) }, // 0-100
height: { value: randomInteger(10, 221) }, // 10-220
weight: { value: randomInteger(30, 301) }, // 30-300
n_of_kids: { value: randomInteger(0, 8) }, // 0-7
fam_status: { value: generateFamStatus() },
preferred_pet: { value: generatePet() },
preferred_color: { value: generateColor() },
preferred_movie: {
value: generateMovie(),
},
},
});
然后您可以创建一个特定长度的数组并通过映射调用该函数,以获取要添加的新随机项。
const output = Array(5).fill(0).map(structureTemplateGenerators)
给定一条记录的结构,如何随机模拟n条相同结构的记录?
例子
假设我有一个记录数组,例如:
[
{
"id": 12345,
"createdAt": "2021-12-25",
"data": {
"age": {"value": 25},
"height": {"value": 100},
"weight": {"value": 160},
"n_of_kids": {"value": 0},
"fam_status": {"value": "married"},
"preferred_pet": {"value": "dog"},
"preferred_color": {"value": "purple"},
"preferred_movie": {"value": "titanic"}
}
},
{...} // another record
]
我的任务:我想模拟一个n条记录的数组,与上面的结构相同
注意。我特别想找到一个适用于任何给定结构的解决方案。因此,虽然我知道这里给出的结构是次优的(例如,冗余 value
属性 并没有增加太多),但我仍然希望能够解释任何可能的给定结构.
我可以解决这个问题的一种方法是创建一个对象,其 值 是指定每个值应该是什么的正则表达式。
const structureTemplateRegex = {
id: "^[0-9]{5}$", // 5-digit number
createdAt: /^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$/, // yyyy-mm-dd
data: {
age: { value: "/^(?:[0-9]|[1-9][0-9]|100)$/" }, // 0-100
height: { value: "/^(?:1[0-9]|[2-9][0-9]|1[0-9]{2}|2[01][0-9]|220)$/" }, // 10-220
weight: { value: '/^(?:3[0-9]|[4-9][0-9]|[12][0-9]{2}|300)$/' }, // 30-300
n_of_kids: { value: '/^(0|[1-9][0-9]?|7)$/' }, // 0-7
fam_status: { value: '/^(married|single|divorced|widowed)$/' },
preferred_pet: { value: '/^(dog|cat|hamster|fish|rabbit|zebra)$/' },
preferred_color: { value: '/^(red|green|yellow|black|orange|blue)$/' },
preferred_movie: {
value: '/^(titanic|alien|se7en|batman|goodfellas|argo)$/',
},
},
};
嗯,structureTemplateRegex
可能适合验证,但不适合生成数据。所以另一种解决问题的方法是为记录中的每个 属性 编写一个生成器函数。
const generateId = (n = 5) => [...Array(n)].map(_=>Math.random()*10|0).join`` //
const generateDate = (start = new Date(2018, 8, 9), end = new Date(2021, 12, 15)) => new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toISOString().slice(0,10); //
const randomInteger = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; //
const randomElement = (arr) => arr[(Math.random() * arr.length) | 0] //
const generateFamStatus = () => randomElement(["married", "single", "divorced", "widowed"])
const generatePet = () => randomElement(["dog", "cat", "hamster", "fish", "rabbit", "zebra"])
const generateColor = () => randomElement(["red", "green", "yellow", "black", "orange", "blue"])
const generateMovie = () => randomElement(["titanic", "alien", "se7en", "batman", "goodfellas", "argo"])
// and then
const structureTemplateGenerators = {
id: generateId(), // 5-digit number
createdAt: generateDate(), // yyyy-mm-dd
data: {
age: { value: randomInteger(0, 101) }, // 0-100
height: { value: randomInteger(10, 221) }, // 10-220
weight: { value: randomInteger(30, 301) }, // 30-300
n_of_kids: { value: randomInteger(0, 8) }, // 0-7
fam_status: { value: generateFamStatus() },
preferred_pet: { value: generatePet() },
preferred_color: { value: generateColor() },
preferred_movie: {
value: generateMovie(),
},
},
};
但我不太确定如何沿着这条路走下去。我有我需要的材料,但没有技术。本质上,我想要的是调用一个函数,该函数将以下参数作为参数:(1) 一个代表性记录的结构,以及 (2) n
要模拟的记录数。该函数将 return 一个长度为 n
的数组,其中包含随机生成的记录。
// pseudocode
generateRecords(structureTemplateGenerators, 5) // but `n` could potentially be 10 or 10000 or 3e7
// would return
const possibleOutput = [
{
id: 12045,
createdAt: '2021-02-21',
data: {
age: { value: 15 },
height: { value: 80 },
weight: { value: 100 },
n_of_kids: { value: 1 },
fam_status: { value: 'widowed' },
preferred_pet: { value: 'dog' },
preferred_color: { value: 'purple' },
preferred_movie: { value: 'se7en' },
},
},
{
id: 39847,
createdAt: '2020-12-02',
data: {
age: { value: 33 },
height: { value: 56 },
weight: { value: 210 },
n_of_kids: { value: 3 },
fam_status: { value: 'married' },
preferred_pet: { value: 'zebra' },
preferred_color: { value: 'blue' },
preferred_movie: { value: 'argo' },
},
},
{
id: 22435,
createdAt: '2018-10-10',
data: {
age: { value: 25 },
height: { value: 103 },
weight: { value: 165 },
n_of_kids: { value: 5 },
fam_status: { value: 'married' },
preferred_pet: { value: 'dog' },
preferred_color: { value: 'green' },
preferred_movie: { value: 'titanic' },
},
},
{
id: 61194,
createdAt: '2019-04-10',
data: {
age: { value: 20 },
height: { value: 90 },
weight: { value: 100 },
n_of_kids: { value: 3 },
fam_status: { value: 'divorced' },
preferred_pet: { value: 'hamster' },
preferred_color: { value: 'blue' },
preferred_movie: { value: 'batman' },
},
},
{
id: 22231,
createdAt: '2021-10-01',
data: {
age: { value: 77 },
height: { value: 160 },
weight: { value: 69 },
n_of_kids: { value: 1 },
fam_status: { value: 'divorced' },
preferred_pet: { value: 'dog' },
preferred_color: { value: 'red' },
preferred_movie: { value: 'titanic' },
},
},
];
更多上下文
我有一个 JavaScript 应用程序,它接受一组记录并对这些数据进行大量聚合计算。最终,应用程序 return 的输出类似于 JSON
。知道输入记录的结构,我想模拟,随机,一个包含n条记录的数组.这样的程序将允许我在 (1) 计算可靠性和 (2) 速度(随着 n 增加)方面测试我的应用程序。
structureTemplateGenerators 应该是 returns 一个新生成的数据结构的函数。现在,它只是创建一个已经设置了值的结构。
const structureTemplateGenerators = () => ({
id: generateId(), // 5-digit number
createdAt: generateDate(), // yyyy-mm-dd
data: {
age: { value: randomInteger(0, 101) }, // 0-100
height: { value: randomInteger(10, 221) }, // 10-220
weight: { value: randomInteger(30, 301) }, // 30-300
n_of_kids: { value: randomInteger(0, 8) }, // 0-7
fam_status: { value: generateFamStatus() },
preferred_pet: { value: generatePet() },
preferred_color: { value: generateColor() },
preferred_movie: {
value: generateMovie(),
},
},
});
然后您可以创建一个特定长度的数组并通过映射调用该函数,以获取要添加的新随机项。
const output = Array(5).fill(0).map(structureTemplateGenerators)