【问题标题】:Spread an object into a table将对象展开到表格中
【发布时间】:2021-04-05 19:33:03
【问题描述】:

我正在寻找一种简单(希望简洁)的方法来转换这种形式的对象:

const object = {
    key1: [a, b],
    key2: [x, y, z]
};

到这里:

[key1, a, key1, b, key2, x, key2, y, key2, z]

到目前为止,我所拥有的是:

const table = Object.entries(object).map(entry => [entry[0], ...entry[1]]);

这给了我这个:

[key1, a, b, key2, x, y, z]

我该如何前进?

【问题讨论】:

  • 知道了:const table = Object.entries(object).map(entry => entry[1].map(value => [entry[0], value]).reduce((acc, val) => [...acc, ...val], []));.
  • 您也应该将其作为答案发布...拥有多种(这将是 4 种)方法来获得所需的输出不会有什么坏处
  • @Nick:我实际上希望简化那个,有什么想法吗?
  • 我认为有几个不使用flat的答案效率更高

标签: javascript node.js arrays object


【解决方案1】:

最简洁、干净和优雅的方法是将 Object.entries() 和 flat() 与作为参数发送到 flat 方法的度数结合起来。

注意:flat()- 作用于数组并将数组展平到参数中发送的程度。它返回一个新的展平数组。例如:

let arr = [1, 2, [3]];
let arrDegree1 = arr.flat();
console.log(arrDegree1) //[1,2,3];

let arr2 = [1, 2, [[3]]]
let arrDegreeTwo = arr2.flat(2);
console.log(arrDegreeTwo) //[1,2,3];

因此解决方案是:

const o = {
  key1: ['a', 'b'],
  key2: ['x', 'y', 'z']
};

const result = Object.entries(o).reduce((acc,[key, values])=>{
  return [...acc, (values.map(v=> [key,...v])) ];
},[]).flat(2);

console.log("Result",result);

【讨论】:

  • 感谢您的指出!已修改代码!
【解决方案2】:

方法一,使用Object.entriesmapflat
方法二,使用Object.entriesforEachpush

const object = {
  key1: ["a", "b"],
  key2: ["x", "y", "z"],
};

// Method 1, Using Object.entries, map and flat
const res = Object.entries(object)
  .map(([key, arr]) => arr.map((value) => [key, value]))
  .flat(2);

// Method 2, Using Object.entries, forEach and push
const toArr = (obj) => {
  const res = [];
  Object.entries(object).forEach(([key, arr]) =>
    arr.forEach((value) => res.push(key, value))
  );
  return res;
};

console.log(res)
console.log(toArr(object));

【讨论】:

    【解决方案3】:

    在旧的 Node 版本上,您可以使用 Array#concat 和扩展语法 [].concat(...array) 来展平数组,使用与 other answers 相同的整体方法:

    const object = {
      key1: [1, 2],
      key2: [3, 4, 5]
    };
    
    const result = [].concat(
      ...Object.entries(object)
        .map(([k, v]) => 
          [].concat(...v.map(e => [k, e]))
        )
    );
    console.log(result);

    如果你经常把东西弄平,你可以把它变成一个函数,然后把它埋在你的实用程序文件中,这样它读起来会更干净一些:

    const flat = a => [].concat(...a);
    const flatMap = (a, fn) => flat(a.map(fn));
    
    const object = {
      key1: [1, 2],
      key2: [3, 4, 5]
    };
    
    const result = flatMap(
      Object.entries(object),
      ([k, v]) => flatMap(v, e => [k, e])
    );
    console.log(result);

    【讨论】:

      【解决方案4】:

      使用 map 和 flat() 可以达到效果

      const object = {
          key1: ['a', 'b'],
          key2: ['x', 'y', 'z']
      };
      
      
      Object.keys(object).map((e, i )=> { 
          return Object.values(object[e]).map( v => { return [e, v]}).flat()
      }).flat()
      // ["key1", "a", "key1", "b", "key2", "x", "key2", "y", "key2", "z"]
      

      【讨论】:

      • 您可以在最后一次调用中使用flat(2) 消除所有嵌套的flat 调用。
      【解决方案5】:

      您可以使用 Object.entries() 获取对象的条目并使用双重嵌套的 .flatMap() 一个映射条目,另一个用于将实际值数组映射为 [key, value] 对,如下所示:

      const object = {
        key1: ['a', 'b'],
        key2: ['x', 'y', 'z']
      };
      const res = Object.entries(object).flatMap(([k, vals]) => vals.flatMap(v => [k, v]));
      console.log(res);

      如果没有 flatMap,您可以使用 .concat().reduce() 以及 spread syntax (...):

      const object = {
        key1: ['a', 'b'],
        key2: ['x', 'y', 'z']
      };
      const res = Object.entries(object).reduce(
        (acc, [key, vals]) => acc.concat(...vals.map(v => [key, v])), []);
      console.log(res);

      【讨论】:

      • TypeError: Object.entries(...).flatMap is not a function
      • 我使用的是 NodeJS,而不是浏览器(我认为这是上述错误的原因)。
      • @goodvibration 你用的是什么版本的nodejs?这将在以后的版本中起作用。节点
      • 我正在使用节点 v10.16.0。
      • 按照您的回答:const table = Object.entries(object).reduce((acc, [key, values]) => [...acc, ...values.map(value => [key, value])], []);。谢谢!!!
      【解决方案6】:

      您可以在对象条目上使用Array.reduce,将键/值对推送到值中每个条目的累加器:

      const object = {
        key1: ['a', 'b'],
        key2: ['x', 'y', 'z']
      };
      
      const result = Object.entries(object)
        .reduce((c, [k, a]) => {
          a.forEach(v =>
            c.push(k, v)
          );
          return c;
        }, []);
      
      console.log(result);

      【讨论】:

        【解决方案7】:

        您可以轻松地做到这一点,而无需使用 flat() 方法。您可以使用 reduce 和 forEach 来实现这一点。

        obj = {'key1': [1,2,3], 'key2': [4,5,6]};
        
        ret = Object.keys(obj).reduce((prev, curr) => {
            obj[curr].forEach(item => { prev = [...prev, curr, item]; });
            return prev;
        }, []);
        console.log(ret);

        【讨论】:

        • 是的,我尝试了flat,但为此获得了not a function。我认为 NodeJS 不支持它。
        • @goodvibration 更新了没有 flat() 的代码
        猜你喜欢
        • 2018-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多