从数组中有效地或更具功能地创建对象

时间:2017-01-19 00:21:30

标签: javascript object

是否有更实用的方法以编程方式在JavaScript中创建对象而无需单独分配每个密钥?

例如,给定此数组(假设它来自外部数据源):

let arr = ['a=1', 'b=2', 'c=3'];

将此转换为对象的简单方法是什么?

let expectedResult = { a: '1', b: '2', c: '3'};

分配一个新对象并使用forforeach循环元素是很笨拙的。如果有类似于map的东西可以产生这样的最终结果,那就太好了。

想象一下,你可以这样做:

arr
  .map(item => new KeyValuePair(itemKey, itemValue)) // magically get itemKey/itemValue
  .toObjectFromKeyValuePairs();

那就是它。但当然没有内置的功能。

4 个答案:

答案 0 :(得分:3)

如果您正在寻找更具功能性的代码方法,可以使用Lodash这样的库,使代码更简洁。

您可以使用_.fromPairs将数组中的数据对转换为对象的键值对。



const convert = arr => _(arr)
    .map(s => _.split(s, '=', 2))
    .fromPairs()
    .value();
console.log(convert(['a=1', 'b=2', 'c=3']));

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

您可以使用reducesplitslice

var arr = ['a=1', 'b=2', 'c=3'];

var out = arr.reduce(
  function (output, input) {
    if (typeof input === 'string') {
      var key = input.split('=',1)[0];
      output[key] = input.slice( key.length + 1 );
    }
    return output;
  },
  {}
);

我使用split的第二个参数使其在找到第一个=后停止。然后在slice上使用input(将其视为字符数组),允许值包含=分隔符,与a=b=c的情况一样。

使用slicevalue将始终是一个字符串,即使它是空字符串。如果要使用空值,可以将行更改为:

output[key || null] = input.slice( key.length + 1 ) || null;

由于split在null和undefined上抛出错误,因此存在字符串的类型检查。

例如,如果您想解析当前页面的查询字符串,可以使用上述技术来完成此操作:

function getQueryStringParams() {
  var reEncodedSpace = /\+/g;
  return location.search.length > 1 // returns false if length is too short
    && location.search.slice( 1 ).split( '&' ).reduce(
      ( output, input ) => {
        if ( input.length ) {
          if ( output === false ) output = {};
          input = input.replace( reEncodedSpace, ' ' ); //transport decode
          let key = input.split( '=', 1 )[ 0 ]; // Get first section as string
          let value = decodeURIComponent( input.slice( key.length + 1) ); // rest is value
          key = decodeURIComponent( key ); // transport decode

          // The standard supports multiple values per key.
          // Using 'hasOwnProperty' to detect if key is pressent in output,
          // and using it from Object.prototype instead of the output object
          // to prevent a key of 'hasOwnProperty' to break the code.
          if ( Object.prototype.hasOwnProperty.call( output, key ) ) {
            if ( Array.isArray( output[ key ] ) ) {
              // Third or more values: add value to array
              output[ key ].push( value );
            } else {
              // Second value of key: convert to array.
              output[ key ] = [ output[ key ], value ];
            }
          } else {
            // First value of key: set value as string.
            output[ key ] = value;
          }
        }
        return output;
      },
      false
    );
}

如果搜索为空,则函数返回false

答案 2 :(得分:0)

如果您愿意再增加一行申报,这可能对您有用。虽然使用像lodash或下划线这样的库,如其他答案中提到的肯定会有所帮助:

var arr = ['a=1', 'b=2', 'c=3'];
var expectedResult = {};
arr.map(function(value) { 
    var kv = value.split("="); 
    expectedResult[kv[0]] = kv[1]; 
    return value    
})

答案 3 :(得分:0)

尝试以下代码。

let arr = ['a=1', 'b=2', 'c=3'];
let b=arr.toString();
b='{"'+(b.split('=').join('":"').split(',').join('","'))+'"}';
b=$.parseJSON(b);
console.log(b);

您将获得所需的输出。