简体   繁体   English

将3层阵列映射到对象集合

[英]Mapping 3 tiers of arrays to collection of objects

I'm struggling to get a 3 tier grouping of arrays to map correctly to a single collection of objects with each tier as a key name of the object and the array value as the key value. 我正在努力获得一个三层的数组分组,以正确地映射到单个对象集合,其中每一层是对象的键名,而数组值是键值。

The three arrays relate to each other by tier and are structured as follows: 这三个数组按层相互关联,其结构如下:

{
  tier1: ['tier1-item1', 'tier1-item2'],
  tier2: ['tier2-item1', 'tier2-item2', 'tier2-item3', 'tier2-item4', 'tier2-item5'],
  tier3: ['tier3-item1', 'tier3-item2', 'tier3-item3']
}

They need to result in an array of objects in as follows: 它们需要按以下方式生成对象数组:

[
  {tier1: "tier1-item1", tier2: "tier2-item1", tier3: "tier3-item1"},
  {tier1: "tier1-item1", tier2: "tier2-item2", tier3: "tier3-item1"},
  {tier1: "tier1-item1", tier2: "tier2-item3", tier3: "tier3-item1"},
  {tier1: "tier1-item1", tier2: "tier2-item4", tier3: "tier3-item1"},
  {tier1: "tier1-item1", tier2: "tier2-item5", tier3: "tier3-item1"},

  {tier1: "tier1-item2", tier2: "tier2-item1", tier3: "tier3-item1"},
  {tier1: "tier1-item2", tier2: "tier2-item2", tier3: "tier3-item1"},
  {tier1: "tier1-item2", tier2: "tier2-item3", tier3: "tier3-item1"},
  {tier1: "tier1-item2", tier2: "tier2-item4", tier3: "tier3-item1"},
  {tier1: "tier1-item2", tier2: "tier2-item5", tier3: "tier3-item1"},

  {tier1: "tier1-item1", tier2: "tier2-item1", tier3: "tier3-item2"},
  {tier1: "tier1-item1", tier2: "tier2-item2", tier3: "tier3-item2"},
  {tier1: "tier1-item1", tier2: "tier2-item3", tier3: "tier3-item2"},
  {tier1: "tier1-item1", tier2: "tier2-item4", tier3: "tier3-item2"},
  {tier1: "tier1-item1", tier2: "tier2-item5", tier3: "tier3-item2"},

  {tier1: "tier1-item2", tier2: "tier2-item1", tier3: "tier3-item2"},
  {tier1: "tier1-item2", tier2: "tier2-item2", tier3: "tier3-item2"},
  {tier1: "tier1-item2", tier2: "tier2-item3", tier3: "tier3-item2"},
  {tier1: "tier1-item2", tier2: "tier2-item4", tier3: "tier3-item2"},
  {tier1: "tier1-item2", tier2: "tier2-item5", tier3: "tier3-item2"},

  {tier1: "tier1-item1", tier2: "tier2-item1", tier3: "tier3-item3"},
  {tier1: "tier1-item1", tier2: "tier2-item2", tier3: "tier3-item3"},
  {tier1: "tier1-item1", tier2: "tier2-item3", tier3: "tier3-item3"},
  {tier1: "tier1-item1", tier2: "tier2-item4", tier3: "tier3-item3"},
  {tier1: "tier1-item1", tier2: "tier2-item5", tier3: "tier3-item3"},

  {tier1: "tier1-item2", tier2: "tier2-item1", tier3: "tier3-item3"},
  {tier1: "tier1-item2", tier2: "tier2-item2", tier3: "tier3-item3"},
  {tier1: "tier1-item2", tier2: "tier2-item3", tier3: "tier3-item3"},
  {tier1: "tier1-item2", tier2: "tier2-item4", tier3: "tier3-item3"},
  {tier1: "tier1-item2", tier2: "tier2-item5", tier3: "tier3-item3"},
]

so there is an object for all possible combinations of items. 因此对于所有可能的项目组合都有一个对象。

I'm not necessarily looking for code examples, although they're welcome, more of a conceptual push in the right direction, es5+. 我不一定要寻找代码示例,尽管它们受到欢迎,但更多地是向正确方向es5 +的概念性推动。

You require a simple nested loop as follows: 您需要一个简单的嵌套循环,如下所示:

function(input) {
  let arr = [];
  for (let i = 0; i < input["tier1"].length; i++) {
    for (let j = 0; j < input["tier2"].length; j++) {
      for (let k = 0; k < input["tier3"].length; k++) {
        let obj = {
          tier1: input["tier1"][i],
          tier2: input["tier2"][j],
          tier3: input["tier3"][k]
        };
        arr.push(obj);
      }
    }
  }
  return arr;
}

For a generic solution for n-such tiers, we could do it without nesting as follows: 对于n个这样的层的通用解决方案,我们可以不嵌套而进行如下操作:

function allCombinations(input) {
  let result = [];
  (function recurse(input, n, outObject, outputArray) {
    if (n > Object.keys(input).length) { 
      outputArray.push(outObject);
      return;
    }
    let str = "tier" + n;
    for (let i = 0; i < input[str].length; i++) {
      let obj = Object.assign({}, outObject);
      obj[str] = input[str][i];
      recurse(input, n+1, obj, outputArray);
    }
  })(input, 1, {}, result);
  return result;
}

Basically, we choose every element of a tier, clone it and recurse it for the next tier till we reach the end. 基本上,我们选择一个层的每个元素,对其进行克隆,然后将其递归到下一个层,直到到达终点为止。

You can use reduce to iterate all the data and Set to create an array with unique values. 您可以使用reduce来迭代所有数据,并使用Set来创建具有唯一值的数组。

// pass to reduce an empty object as initial value, let's call it accumulator
data.reduce((accumulator, currentValue, index) => {
  // get single object and iterate its keys
  for(let key in currentValue) {
    // check if accumulator contains already the key
    // if yes
    if (accumulator.hasOwnProperty(key)) {
      // update the Set (internally with automaticcaly remove the duplicate values)
      accumulator[key].add(currentValue[key])
    } else {
      // if not, create the Set
      accumulator[key] = new Set([currentValue[key]]);
    }
  }
  // Have we finish looping?
  // If yes, we have to convert Set to Array
  if (index === data.length - 1) {
    const finalObject = {};
    Object.keys(accumulator).forEach(singleKey => {
      finalObject[singleKey] = Array.from(accumulator[singleKey]);
    })
    return finalObject;
  } else {
    // if not we continue
   return accumulator 
  }
}, {});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM