Typescript将字符串转换为Map

时间:2019-05-14 09:57:14

标签: javascript arrays string split

我有这个字符串(称为currentExecution.variables):

{executionid=0c3246fb37e65e3368c8c4f30000016ab593bec244daa8df, timeout=10000}

,我需要将其转换为Map,以便可以处理条目,但是这样做很难。在this answer之后,我尝试将其转换为键值对对。首先,我将=替换为:,并将{或}替换为空格,然后根据答案将其拆分:

newString.split(/,(?=[^,]+:)/).map(s => s.split(': '));

但是我没有得到正确的结果,而且我没有地图就陷入困境。缺少了什么?还是有更好/更快的方法来做到这一点?

4 个答案:

答案 0 :(得分:2)

您可以执行以下操作

  1. 从字符串的开头和结尾删除{}字符。请勿使用replace,以防其中出现任何情况。
  2. 将结果拆分为形成键值对的每个离散块。
  3. 将它们拆分为实际的键和值
  4. 由于构造函数takes an array where each item is an array with two items可以将结果轻松转换为Map,并将结果转换为map,其中第一项是键,第二项是值:

let string = "{executionid=0c3246fb37e65e3368c8c4f30000016ab593bec244daa8df, timeout=10000}";

let keyValuePairs = string.slice(1, -1) //remove first and last character
  .split(/\s*,\s*/)                     //split with optional spaces around the comma
  .map(chunk => chunk.split("="));      //split key=value
  
const map = new Map(keyValuePairs);

console.log(map.get("executionid"));
console.log(map.get("timeout"));

答案 1 :(得分:2)

您也可以不使用正则表达式,但是您必须了解以下基本概念:首先沿,分,然后沿=分:

var data = "{executionid=0c3246fb37e65e3368c8c4f30000016ab593bec244daa8df, timeout=10000}";
var pairs = data.substring(1, data.length - 1).split(", "); // step 1, split using commas

var obj = pairs.reduce(function(acc, cur) {
  var pair = cur.split("="); // step 2, split using =
  acc[pair[0].trim()] = pair[1].trim();
  return acc;
}, {});

console.log(obj);

答案 2 :(得分:1)

您可以在this regex所示的捕获组中捕获键和值对。

基于此,您可以继续进行操作并将其价值减少到地图中。

const currentExecutionVariable = "{executionid=0c3246fb37e65e3368c8c4f30000016ab593bec244daa8df, timeout=10000}";

const pattern = /([A-Za-z0-9]+)\=([A-Za-z0-9]+)/g;

const matches = currentExecutionVariable.match(pattern);

const currentExecutionMap = matches.reduce((acc, curr) => {
	const [key, value] = curr.split('=');
	
	if (!acc.has(key)) {
		acc.set(key, value);
	}	
	return acc;
}, new Map());

for (const [key, value] of currentExecutionMap.entries()) {
  console.log (`${key}: ${value}`);
}


更新

使用捕获的组:

const currentExecutionVariable = "{executionid=0c3246fb37e65e3368c8c4f30000016ab593bec244daa8df, timeout=10000}";

const pattern = /([A-Za-z0-9]+)\=([A-Za-z0-9]+)/g;

let currentExecutionMap = new Map();

let capturedGroup;
while ((capturedGroup = pattern.exec(currentExecutionVariable))) {

  // 1st captured group is the key of the map
  const key = capturedGroup[1];

  // 2nd captured group is the value of the map
  const value = capturedGroup[2];

  if (!currentExecutionMap.has(key)) {
    currentExecutionMap.set(key, value);
  }
}

for (const [key, value] of currentExecutionMap.entries()) {
  console.log(`${key}: ${value}`);
}

答案 3 :(得分:-1)

我有这个字符串(称为统计信息):

active_total: 1087
cumulative: 1
trace_total: 10

甚至不是 JSON 格式。

This 是我正在尝试的解决方案:

let keyValuePairs = stats
  .split(/\s*\n\s*/)                     //split with optional spaces around the comma
  .map(chunk => chunk.split(": "));      //split key=value
  
const map = new Map(keyValuePairs);

console.log(map.get("sessions_active_total"));
console.log(map.get("cumulative"));

但它在这一行抛出编译错误:

const map = new Map(keyValuePairs);

错误信息:

error TS2769: No overload matches this call.
  Overload 1 of 3, '(iterable: Iterable<readonly [unknown, unknown]>): Map<unknown, unknown>', gave the following error.
    Argument of type 'string[][]' is not assignable to parameter of type 'Iterable<readonly [unknown, unknown]>'.
      The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
        Type 'IteratorResult<string[], any>' is not assignable to type 'IteratorResult<readonly [unknown, unknown], any>'.
          Type 'IteratorYieldResult<string[]>' is not assignable to type 'IteratorResult<readonly [unknown, unknown], any>'.
            Type 'IteratorYieldResult<string[]>' is not assignable to type 'IteratorYieldResult<readonly [unknown, unknown]>'.
              Type 'string[]' is not assignable to type 'readonly [unknown, unknown]'.
                Target requires 2 element(s) but source may have fewer.
  Overload 2 of 3, '(entries?: readonly (readonly [unknown, unknown])[]): Map<unknown, unknown>', gave the following error.
    Argument of type 'string[][]' is not assignable to parameter of type 'readonly (readonly [unknown, unknown])[]'.
      Type 'string[]' is not assignable to type 'readonly [unknown, unknown]'.

58         const map = new Map(keyValuePairs);