【问题标题】:How do I create dynamic key names for JavaScript arrays?如何为 JavaScript 数组创建动态键名?
【发布时间】:2023-03-26 22:44:01
【问题描述】:

TL;DR;

我期待这个代码

console.log Object.defineProperty(results,match, {value:[]})

输出类似:

[foo: Array[0]]

这适用于控制台,但不适用于 Jasmine 正在测试的我的代码。

详情

我正在尝试创建一个 JavaScript 哈希。我似乎无法在我的代码中动态创建属性,尽管我能够在 JSFiddle 中做到这一点。我先写测试,代码在 Jasmine 下似乎失败了。不知道是不是茉莉的错。

这是我的fiddle。我是第一次使用 Object.defineProperty 定义属性,但我也尝试过:

if typeof results[match] = 'undefined' then results[match] = []

这也没有用。在我的 Jasmine 代码中,它不会创建属性。

【问题讨论】:

  • 不是执行此操作的标准方法results[match] = results[match] || []; 这比 if 更快
  • 我在阵列上调用 .push。如果数组不存在,也就是说,如果动态属性没有被定义为结果数组上的数组,JavaScript 会抱怨 push 不是“结果”的方法。
  • @Hogan: results[match] ?= [ ] 可能是更惯用的 CoffeeScript。我怀疑任何速度差异都会非常小,不是吗?
  • @muistooshort - 同意

标签: javascript arrays coffeescript jasmine


【解决方案1】:

有几个小问题(上面的 cmets 中提到了几个),更正在代码 cmets 中:

testsForRev = [{
    id: 1
    rev_id: 10
    is_current: true
    test_params: [
      {name: 'device_param1', value: '1/#{1PLACEHOLDER1}'}
      {name: 'device_param2', value: 'TEST/#{2PLACEHOLDER2}/#{3PLACEHOLDER3}'}
      {name: 'test_param1', value: 'NOT_A_PLACEHOLDER'}
    ]
  },{
    id: 2
    rev_id: 10
    test_params: [
      {name: 'device_param3', value: '1/#{4PLACEHOLDER4}'}
      {name: 'device_param4', value: 'TEST/#{5PLACEHOLDER5}/#{6PLACEHOLDER6}'}
      {name: 'test_param2', value: 'NOT_A_PLACEHOLDER'}
      {name: 'device_param7', value: '5/#{4PLACEHOLDER4}'}
    ]
  }]

parseDeviceParams= (test,results) ->
    for param in test.test_params
        param.value.replace /#{(.*?)}/g, (str,match,start, usage) ->

            #conditionally create array for the property. Alternative
            #would be 'results[match] and results[match].push...'
            #which would conditionally activate but not create the
            #empty array if not already present...
            results[match] ?= []
            results[match].push {name: param.name, usage: usage}

            #i've added a return value for the substr, but you were
            #calling just for side effects?
            return match

    return results

aggregate = {} #changed to object, now need to define custom toString

Object.defineProperty aggregate, 'toString',
    value: ->
        str = ''
        for index, value of this
            str += "#{index}: "
            for item in value
                for key, val of item
                    str += "\t#{key}: #{val}\n"

        return str

for test in testsForRev
    parseDeviceParams test, aggregate
console.log "results:\n#{aggregate.toString()}"

fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-16
    • 2010-09-25
    • 2021-11-10
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多