笛卡尔乘积(所有组合),在灵活长度的多元素对象阵列中。

问题描述 投票:0回答:1

在StackOverflow上有几个问题与答案,展示了如何为各种简单数组寻找笛卡尔积。还有一篇关于 罗塞塔代码. 但我找不到任何解决我的问题的方法。

我有一个包含项目的数组对象,我们称它为 items:

let items = [{
   id: 1
   quantity: 2
   field: "other_field"
},
{
   id: 2
   quantity: 3
   field: "other_field"
}]

这个数组中的每个项目都有一个定价方法,我们可以通过要求来接收它。

let pricing = getPricing(id) //item id

/*
Which will return to us:
*/

pricing = [
    {pricing_id: 1, reagent_items: [/*array of objects, fields exactly items*/]},
    {pricing_id: 2, reagent_items: [/*array of objects, fields exactly items*/]}
]

CARTESIAN PRODUCT PROBLEM。

你可能已经明白了,根据答案的标题,我想收到所有可能的项目组合。AND reagent_items from pricing methods.

例如,如果我们有两个项目,而每个项目(其中2个)都只有一种定价方法,那么将有4种不同的组合。

  1. 2个默认项目从 items
  2. 第一个默认项 items (item[0])和所有的试剂_项目从 getPricing 对于 item[1]
  3. 第二个默认项目从 items (item[1])和所有的试剂_项目从 getPricing 对于 item[0]
  4. 两个试剂项目都来自 getPricing 对于两个默认 items

我真的推不动 reagent itemsitems (或从 items)数组,因为项目可以相同(互相包含)代替它。我是用自己的 Array.prototype.method 用于添加删除项目,从 items 阵列。它的作用就像 pushslice 但以更优雅的方式,用 idquantity 字段。

实际的问题在于arrays.length和 for ... loop.

当我们评估默认的笛卡儿乘积时,我们在数组.长度和它的元素之前就知道了,但在我的例子中,我应该 getPricing 每一个项目,然后接收数组方法。

Schema。

就像..:

    Default:        I_1       I_2        ...   N
                   /   \     /   \            / \
Get Pricing:     [I_A, I_B][I_B, I_C]     [IN_J, IN_K],
                                        [IN_Y, IN_X, IN_Z],   

所以它不是关于寻找, Cartesian([I_A, I_B],[I_B, I_C]) 而是类似于:

I_1 + I_2
I_1 + (I_B, I_C)
(I_A, I_B) + I_2
(I_A, I_B) + (I_B, I_C)
...

所以,默认的项目包括每个人和他们的 reagent_items 而且要找到两个项目的所有组合很简单,但当它变成3个以上的时候... ...

我目前的伪代码暂时。

/* inside async*/
...
let ArrayOfPricing = [] //length 2, where each Array represent Array of `pricing` for each item
Promise.all(items.map(async item => {
   const itemPricing = await getPricing(item.id);
   ArrayOfPricing.push(itemPricing );
})

/**And what's next? **/
for (let item of items) {

}

所以我不明白在这个阶段我应该做什么。

  • 我应该循环处理每一个项目吗?但是如果是这样的话,即使我一个一个地遍历每一个项目,然后改变它,并添加它的reagent_items(对于每一个定价),我仍然没有改变数组中的下一个项目元素。items 而且它的长度超过了2,那么我将不会收到所有的组合,它会像。
for items
   ↓
  item[1] → for pricing
               → for reagent_items 
                      ↓
               replace item[1] for all reagent_item

  item[2] /** they are still there, but I need iterate over it's pricing , too **/
  item[3]
  • 或者我可以计算出所有可能的组合,通过寻找。items 长度和所有 pricing 长度,然后形成固定长度的新数组并清空,然后推送给所有组合。但是,如果我用 for loop... 我应该合并项目,这将是 for loop, inside for loop, inside for .. loop..

所以说实话,我是没有办法了。我不要求你代替我写出完整的工作代码,而是给我指出这个循环的出路。如何得到每一个项目的每一个组合和里面的 "宝贝项目"?那我应该用多少个循环?如果有什么有用的ideapseudocodepost链接,能帮助我处理这个案例,我将感激不尽。我也在这里,会查看下面所有的评论和答案。

UPD一个简单版的 "从我得到的,到我想要的"

从这。

[ 
   {
      field: "original, can be cloned for every combination", 
      items: 
         [
            {id: 1, quantity: 2},
            {id: 2, quantity: 3} 
         ]
    }
]

到:

[ 
   {
      field: "original", 
      items: 
         [
            {id: 1, quantity: 2},
            {id: 2, quantity: 3} 
         ]
    },
   {
      field: "combination1", 
      items: 
         [
            {id: 11, quantity: 1}, //from getPricing(item[0])
            {id: 12, quantity: 1}, //from getPricing(item[0])
            {id: 2, quantity: 3} 
         ]
    },
   {
      field: "combination2", 
      items: 
         [
            {id: 1, quantity: 2},
            {id: 22, quantity: 3} //from getPricing(item[1])
            {id: 23, quantity: 3} //from getPricing(item[1])
         ]
    },
   {
      field: "combination3", 
      items: 
         [
            {id: 11, quantity: 1}, //from getPricing(item[0])
            {id: 12, quantity: 1}, //from getPricing(item[0])
            {id: 22, quantity: 3} //from getPricing(item[1])
            {id: 23, quantity: 3} //from getPricing(item[
         ]
    }
    //can be any length according to getPricing of every item, and I modify original array, but we could create a new one.
]
javascript arrays node.js combinatorics cartesian-product
1个回答
0
投票

正如我所承诺的,我已经找到了我的问题的解决方案,我想与StackOverflow社区分享。

伪代码。

let array = [ 
   {
      field: "original, can be cloned for every combination", 
      items: 
         [
            {id: 1, quantity: 2},
            {id: 2, quantity: 3} 
         ]
    }
]


for (let element of array) {
    let MethodsCombinations = [];
    for await (let forCombinations of element.items.map((item, i) => {
        return getMethod(item.id) //get Method for each item)
    })) {
        MethodsCombinations.push(forCombinations)
    }
    /* Cartesian product */
     let vanilla_CartesianProduct = MethodsCombinations.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []));
    /* Return array of arrays, with objects inside like default array */ 
    /**
    * Other logic with two for loops and merging all the combinations and quantities 
    * with (my own) modified Array.prototype.addItemToArray
    */

}

我非常感谢这个 Nina Scholz的回答她的真棒StackOverflow 的所有答案的组合spermutations的个人资料,并提供支持。

© www.soinside.com 2019 - 2024. All rights reserved.