【问题标题】:Javascript One-To-One Object Mapping (Built-in Function?)Javascript 一对一对象映射(内置函数?)
【发布时间】:2019-03-28 09:51:18
【问题描述】:

如果我有 2 个数组(propertiesdata):

properties = [name, height, weight, zone];

data = [
  ['Luke Skywalker', 123, 112, 'B'],
  ['Jawa', 12, 8, 'B'],
  ['Hutt', 200, 999, 'C']
];

我想创建一个对象数组 (statistics):

statistics = [{
    name: 'Luke Skywalker',
    height: 123,
    weight: 112,
    zone: 'B'
  },
  {
    name: 'Jawa',
    height: 12,
    weight: 8,
    zone: 'B'
  }, {
    name: 'Hutt',
    height: 200,
    weight: 999,
    zone: 'C'
  }
];

通常我会在data[] 上使用映射,创建一个temp 对象,然后将其推送到statistics[]

但是因为我知道data 中的所有其他条目都具有相同的维度和数据类型。我也知道有一个从propertiesdata 的一对一映射。 javascript中是否有一个内置函数可以输出具有一对一映射的对象数组? properties.mapAll(data) 之类的东西。我希望不要使用库,因为我在 GAS 中的模板 .html 上执行此操作。

【问题讨论】:

  • properties = [name, height, weight, zone]; 这些真的是 4 个独立变量吗?如果是这样,它们是什么?还是您的意思是使用字符串?
  • 对于回答者,google-apps-script 是 es3,带有精选的 es5 函数,如 map、reduce 等。不支持 =>...
  • @TheMaster 请注意,这是在.html 中完成的。没有指定这是作为HtmlTemplate#evaluate 的一部分还是真正的客户端代码完成,因此箭头和 Object.assign 很可能是可用的。

标签: javascript arrays object google-apps-script


【解决方案1】:

如果属性始终为nameheightweightzone,那么您可以使用Array Destructuring 应用占位符名称​​并将值存储到它在map 内。

const data = [['Luke Skywalker', 123, 112, 'B'], ['Jawa', 12, 8, 'B'], ['Hutt', 200, 999, 'C']];

const stats = data.map(([name, height, weight, zone]) => ({
  name, 
  height, 
  weight, 
  zone
}))

console.log(stats)

编辑 基于 GAS 上的脚本。这是相同的方法,但 es5。

var data = [['Luke Skywalker', 123, 112, 'B'], ['Jawa', 12, 8, 'B'], ['Hutt', 200, 999, 'C']];

var stats = data.map(function(dataArray) {
  return {
    name: dataArray[0], 
    height: dataArray[1], 
    weight: dataArray[2], 
    zone: dataArray[3]
  }
})

console.log(stats)

【讨论】:

  • 这种方法不采用动态方法,采用properties
  • 是的,就像我上面说的,因为在 OP 中并不清楚 如果属性总是名称、身高、体重和区域,那么...
  • 在 Apps Script .html 文件中,您可以使用现代 JavaScript,只要正在编写的代码在“运行时”进行评估。如果在调用HtmlTemplate#evaluate的过程中正在执行代码,那么可能JS语法需要与JS 1.6 (+ Array filter/map/every/some/reduce methods)保持一致。
【解决方案2】:

您可以通过获取用于构建命名键的属性数组来映射新对象,并使用Object.assign 收集所有对象。

var properties = ['name', 'height', 'weight', 'zone'],
    data = [['Luke Skywalker', 123, 112, 'B'], ['Jawa', 12, 8, 'B'], ['Hutt', 200, 999, 'C']],
    statistics = data.map(a => Object.assign(...properties.map((k, i) => ({ [k]: a[i] }))));

console.log(statistics);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案3】:

    您可以使用Array#mapArray#reduce 方法。使用Array#map 方法遍历第二个数组,其中使用Array#reduce 方法生成对象并返回。

    let res = data.map(arr => properties.reduce((obj, k, i) => Object.assign(obj, { [k]: arr[i] }), {}));
    

    let properties = ['name', 'height', 'weight', 'zone'],
    
      data = [
        ['Luke Skywalker', 123, 112, 'B'],
        ['Jawa', 12, 8, 'B'],
        ['Hutt', 200, 999, 'C']
      ];
    
    let res = data.map(arr => properties.reduce((obj, k, i) => Object.assign(obj, { [k]: arr[i] }), {}));
    
    console.log(res)

    let res = data.map(arr => properties.reduce((obj, k, i) => (obj[k] = arr[i], obj)), {}));
    

    let properties = ['name', 'height', 'weight', 'zone'],
    
      data = [
        ['Luke Skywalker', 123, 112, 'B'],
        ['Jawa', 12, 8, 'B'],
        ['Hutt', 200, 999, 'C']
      ];
    
    let res = data.map(arr => properties.reduce((obj, k, i) => (obj[k] = arr[i], obj), {}));
    
    console.log(res)

    【讨论】:

      【解决方案4】:

      您可以使用Array Destructuring 提取值并将它们替换为返回的对象中的命名属性。

      data.map(([name, height, weight, zone]) => ({name, height, weight, zone}));
      

      let data = [['Luke Skywalker', 123, 112, 'B'], ['Jawa', 12, 8, 'B'], ['Hutt', 200, 999, 'C']],
      
      result = data.map(([name, height, weight, zone]) => ({name, height, weight, zone}));
      
      
      console.log(r);

      【讨论】:

      • 这与@FrancisLeigh 之前的回答有什么不同吗? stackoverflow.com/a/55394677/9337071除了你的回答信息少?
      • @tehhowch 啊!我很抱歉。我没有意识到这是相同的句法答案。我稍后会删除这个答案:)
      猜你喜欢
      • 1970-01-01
      • 2019-09-19
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      相关资源
      最近更新 更多