我正在尝试编写一个程序,该程序根据我的JSON结构生成每个项目,并为每个组合提供一个单独的编号。我在这里找到了一个函数,到目前为止,它的工作为我列出了每个组合,但是我无法破译代码,以至于我什至不明白它的作用。它给了我所有项目,像Key : Value一样听,但老实说,我不知道代码的哪一部分做了什么,我无法访问它以构建我给他们的唯一数字。这是我在这里找到的代码(丢失了线程(:
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) ? v : [v]).forEach(w =>
(w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var input = { bookSet: { book: ["book1", "book2", "book3"], title: ["title1", "title2"], author: ["author1"], publisher: ["publisher1"] } },
cartesian = { eachBook: getCartesian(input.bookSet) };
它只是用太高级的语法编写的,我无法远程理解我必须插入自己进行任何计算的位置。我想我要求的要么是一个解释,要么是一个更容易理解和可修改的代码。我绝对需要像这样运行所有元素,从我目前所能知道的输出看起来很棒,我只需要以某种方式计算键并输出每个对象的元素组合键的数字。 例如,第 243 册的标题 2、作者 4 和出版商 3。我希望任何人都能理解这一点。多谢!
编辑:包括我自己的数据和所需的输出。我显示的组合不需要有意义。
var Product = {
json: { Product : {
assortment: [
{
name: "Yoghurt",
Flavor: ["natural", "honey", "stracciatella"],
Kind: ["greek", "soy"],
},
{
name: "Sauce",
},
{
name: "Milk Drink",
}
],
Brand: ["Oatly", "Dannon"],
Containment: ["Cup", "Jar"]
}}};
我的输出我想生成所有这些的组合,并最终计算以下屏幕截图中右侧的数字
给定C_1
和C_2
两个集合
C_1
和C_2
的笛卡尔乘积
由C_1 x C_2 = {(c_1_i,c_2_j) for c_1_i in C_1, c_2_j in C_2}
给出
您可以通过考虑(C_1 x C_2)
(您之前计算的(并将每个C_3
的 elem "相邻"到一个元组来构建C_1 x C_2 x C_3
C_1 x C_2
等等
const cartesianProduct = (C, D) => {
const res = []
C.forEach(c => {
D.forEach(d => {
// in case the tuple contains only one element (the initialization)
// make the elmeent into a tuple
const tuple = Array.isArray(c) ? c : [c]
res.push([...tuple,d])
})
})
return res
}
const nCartesianProduct = (Cs_n) => {
// we adjoin each elem of C_i and we "grow"
return Cs_n.reduce((res, C_i) => cartesianProduct(res, C_i))
}
console.log(nCartesianProduct([['b1', 'b2', 'b3'], ['t1', 't2'], ['a'], ['p']]))
这是我试图用一个简单的术语来阐述:
让我们假设一个例子
const sets = [ [1], [1,2], [1,2,3] ]
可能的组合可以记录如下:
1 1 1 1 2 1
1 1 2 -> 1 2 2
1 1 3 1 2 3
让我们将其视为一个时钟,一旦达到最大值,最后一行将增加前一行的值。换句话说:让我们增加最后一行的 i 位置,当超过限制时 ->将其降至零并增加同级,如果同级超过顶部 ->重复。
请考虑以下代码:
let sets = [[1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5] ];
let state = sets.map( () => 0 );
console.log(sets, state);
function handleIncreament(i){
if( state[i] >= sets[i].length){
if(i-1 < 0) {
console.log('end of the row');
return false;
}
state[i] = 0;
state[i-1] += 1;
return handleIncreament(i-1);
}
else {
return true;
}
}
while( handleIncreament(state.length - 1) ){
console.log( state );
state[state.length - 1]++;
}
以上将记录如下:
(4) [Array(2), Array(3), Array(4), Array(5)] (4) [0, 0, 0, 0]
(4) [0, 0, 0, 0]
(4) [0, 0, 0, 1]
(4) [0, 0, 0, 2]
(4) [0, 0, 0, 3]
(4) [0, 0, 0, 4]
(4) [0, 0, 1, 0]
(4) [0, 0, 1, 1]
(4) [0, 0, 1, 2]
...
(4) [1, 2, 3, 4]
end of the row
4
这样,让我们将其应用于您的示例:
const test = { bookSet: { book: ["book1", "book2", "book3"], title: ["title1", "title2"], author: ["author1"], publisher: ["publisher1"] } };
sets = Object.values(test.bookSet);
state = sets.map( () => 0 );
console.log(sets, state);
const matches = [];
while( handleIncreament(state.length - 1) ){
const match = sets[0][state[0]] + ' ' + sets[1][state[1]] + ' ' + sets[2][state[2]] + ' ' + sets[3][state[3]];
matches.push( match );
state[state.length - 1]++
}
console.log(matches);
并期望获得以下内容:
["book1 title1 author1 publisher1", "book1 title2 author1 publisher1", "book2 title1 author1 publisher1", "book2 title2 author1 publisher1", "book3 title1 author1 publisher1", "book3 title2 author1 publisher1"]
您可以获取上述数据而不添加多余的部分,并通过创建嵌套属性的平面数组来简化结果。
结果图片的数字不包括在内,因为每个值与给定数据集的关系缺失。
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) ? v : [v]).forEach(w =>
(w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var data = {
assortment: [
{
name: "Yoghurt",
Flavor: ["natural", "honey", "stracciatella"],
Kind: ["greek", "soy"],
},
{
name: "Sauce",
},
{
name: "Milk Drink",
}
],
Brand: ["Oatly", "Dannon"],
Containment: ["Cup", "Jar"]
},
result = getCartesian(data)
.map(({ assortment: { name, Flavor = '', Kind = '' }, d = '', Brand, f = '', Containment, h = '', i = '', j = '' }) =>
[name, Flavor, Kind, d, Brand, f, Containment, h, i, j]);
console.log(result.length);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }