[英]Making an object array to have all combinations of possibilities from 3 Arrays using javascript / typescript
我正在尝试创建一个对象数组,该对象数组将包含代表三个字符串数组提供的每种组合可能性方案的对象。 我的对象数组(集合)中的每个对象都应包含属性{format: '', iconType: '', state: ''}
,其中每个属性可以是字符串或null值。
所以在我的代码中,我有3个字符串数组...就像这样:
const buttonFormats = ['compact', 'regular', 'fluid'];
const stateParams = [
null,
'secondary',
'2',
'tertiary',
'3',
'warning',
'!',
'danger',
'!!!',
'danger-secondary',
'2!!!',
'primary-line',
'1l',
'secondary-line',
'2l',
'tertiary-line',
'3l',
'warning-line',
'!l',
'danger-line',
'!!!l'
];
const iconTypes = [null, 'add', 'edit'];
const allCombinations = [];
我的计划是要有三个嵌套循环,我们将一个循环的当前值与另一个循环的值组合起来,就像这样……
public makeButtonStates(): any[] {
const buttonFormats = ['compact', 'regular', 'fluid'];
const stateParams = [
null,
'secondary',
'2',
'tertiary',
'3',
'warning',
'!',
'danger',
'!!!',
'danger-secondary',
'2!!!',
'primary-line',
'1l',
'secondary-line',
'2l',
'tertiary-line',
'3l',
'warning-line',
'!l',
'danger-line',
'!!!l'
];
const iconTypes = [null, 'add', 'edit']; // these are the available icons
const allCombinations = [];
buttonFormats.forEach((format) => {
const currentCombinaton: any = {};
currentCombinaton.format = format;
iconTypes.forEach((icon) => {
currentCombinaton.iconType = icon;
stateParams.forEach((state) => {
currentCombinaton.state = state;
console.log(currentCombinaton);
allCombinations.push(currentCombinaton);
});
});
});
return allCombinations;
}
public ngOnInit(): void {
this.buttonStates = this.makeButtonStates();
console.log(this.buttonStates);
}
这并不起作用,好像当我使用console.log()
输出当前值的组合时,写到控制台的正是我所期望的,但是当我编写嵌套循环函数的结果时,就得到了它的值this.buttonStates
对象数组中所有对象中的this.buttonStates
或allCombinations
对于iconType和state属性具有相同的值,这是字符串数组´{iconType:“ edit”,state:“ !!! l”}中的最后一次。开发人员控制台的此屏幕快照给出了输出的概念...
显然,我的执行是错误的,我应该使用.map
或.filter
或.reduce
,而不是为什么我的输出数组只取stateParams和iconType数组的最后一个值?
如果您能帮助我发现这个问题,请先谢谢。
如果没有嵌套循环,则可以对值采用组合算法,然后再应用对象结构。
const buttonFormats = ['compact', 'regular', 'fluid'], iconTypes = [null, 'add', 'edit'], stateParams = [ null, 'secondary', '2', 'tertiary', '3', 'warning', '!', 'danger', '!!!', 'danger-secondary', '2!!!', 'primary-line', '1l', 'secondary-line', '2l', 'tertiary-line', '3l', 'warning-line', '!l', 'danger-line', '!!!l'], result = [buttonFormats, iconTypes, stateParams] .reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), [])) .map(([format, iconType, state]) => ({ format, iconType, state })); console.log(result.length); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以运行一组嵌套的循环,我不确定是否存在更有效的方法:
const buttonFormats = ['compact', 'regular', 'fluid']; const iconTypes = [null, 'add', 'edit']; const states = [null, 'secondary', '2', 'tertiary', '3', 'warning', '!', 'danger', '!!!', 'danger-secondary', '2!!!', 'primary-line', '1l', 'secondary-line', '2l', 'tertiary-line', '3l', 'warning-line', '!l', 'danger-line', '!!!l']; const allCombinations = []; buttonFormats.forEach((bf) => { iconTypes.forEach((it) => { states.forEach((s) => { allCombinations.push({ format: bf, icon: it, state: s }); }); }); }); console.log(allCombinations);
关键区别在于定义对象的时间。 也就是说,如果我在外部循环中或循环外部定义了const
,我将重用对同一对象的引用(这意味着我最终在代码的嵌套部分中更新了同一对象)。 通过在最内层的循环中创建一个新对象,可以避免这种情况。
这称为笛卡尔乘积 。 通常,它是基于以下观察以递归方式编写的:
要获得N个数组的笛卡尔积Cn,计算N-1个数组的积Cn-1,然后将第一个数组的每个元素与Cn-1中的每个元素合并
这是功能样式的示例实现
flatMap = (xs, f) => [].concat(...xs.map(f)) prepend = x => ys => [x].concat(ys) prependEach = (xs, yss) => flatMap(xs, x => yss.map(prepend(x))) product = (xs, ...rest) => xs ? prependEach(xs, product(...rest)) : [[]] // demo a = [1,2,3] b = ['A', 'B', 'C'] c = ['foo', 'bar'] g = product(a, b, c) g.forEach(x => console.log(x.join('-')))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.