解析数组并将值转换为对象

时间:2019-10-24 15:27:51

标签: javascript arrays regex

我有一个数组,需要将其转换为具有给定值的对象。

这是输入数组

let actions = ['CREATE: id=14&amount=800&currency=USD','FINALIZE: id=14&amount=800&currency=USD','PAY: id=14' 
]

我怎么把它变成这个对象。

let result ={
 'create': 800,
 'finalize': 800,
 'pay':14
}

到目前为止,我有一个循环来检查数组中的键是否可用,但是我在接下来的步骤中迷路了。一位同事说,正则表达式可能是最好的选择。

for(let x = 0; x <=actions.length;x++){
    if(actions[x].icludes('CREATE')){

    } else(actions[x].icludes('FINALIZE')){

    } else(actions[x].icludes('PAY')){

    }
}

感谢蚂蚁的帮助。

4 个答案:

答案 0 :(得分:2)

您可以在:\s+处拆分每个字符串,以获取密钥和要分析的字符串。您将在结果数组中获得2个值。使用destructuring来使它们分开变量

["CREATE", "id=14&amount=800&currency=USD"]

然后在第二个值上使用URLSearchParams构造函数从查询字符串获取键值对。

某些键需要amount,而有些键需要id的值。因此,您可以创建一个映射器对象。这将在URLSearchParams中映射具有 name 的键。

const mapper = {
  PAY: "id",
  CREATE: 'amount',
  FINALIZE: 'amount',
  default: "amount"
};

在这里,PAY需要id值。如果有更多键,则可以在此处添加。您也可以将CREATE: "amount"添加到该对象。但是,由于那是default,所以我跳过了。如果在default中找不到密钥,则可以使用mapper密钥。从解析函数返回带有键和值的对象。

然后reduce数组并合并每个已解析的对象以创建输出

const actions = ['CREATE: id=14&amount=800&currency=USD', 'FINALIZE: id=14&amount=800&currency=USD', 'PAY: id=14']

const mapper = {
  PAY: "id",
  //CREATE: 'amount', // you could add CREATE and FINALIZE if you want
  default: "amount"
};

function parse(str) {
  const [key, value] = str.split(/:\s+/);
  const param = new URLSearchParams(value).get(mapper[key] || mapper.default);
  return { [key.toLowerCase()]: param };
}

const output = actions.reduce((acc, str) => Object.assign(acc, parse(str)), {});

console.log(output)

答案 1 :(得分:0)

考虑到您的预期输出不会遵循单一结构,我选择返回所有值,而不是返回任意值。无论如何,如果您有一些业务逻辑来证明选择不同的值返回的合理性,则可以轻松地更改代码以适应这种情况。

const actions = [
  'CREATE: id=14&amount=800&currency=USD',
  'FINALIZE: id=14&amount=800&currency=USD',
  'PAY: id=14' 
];

const actionsData = actions.reduce((res, str) => {
  const [op, query] = str.split(': '); 
  
  const kvPairs = query.split('&');
  
  const data = kvPairs.reduce((res, kvStr) => {
    const [key, value] = kvStr.split('=');
    res[key] = value;
    return res;
  }, {});
  
  res[op] = data;
  return res;
}, {});

console.log(actionsData);

答案 2 :(得分:0)

作为正则表达式示例,这也可能起作用。当然,可能总是会有更健壮的正则表达式规则。 (并且更具可扩展性)

for i in range(len(a)): 
    print(a[i]) 

答案 3 :(得分:0)

这是一个解决方案:

let actions = ['CREATE: id=14&amount=800&currency=USD','FINALIZE: id=14&amount=800&    currency=USD','PAY: id=14']
let actionObject = [];

for(let i=0;i<actions.length;i++){

    // Split where it has colon and space
    let splitter = actions[i].split(": ");

    // Get label (and make it lowercase)
    let theLabel = splitter[0].toLowerCase();

    // remove label from array
    splitter.splice(0,1);

    // rejoin array if any values contained colon and space
    splitter = splitter.join(": ");

    // find amount= and split that
    splitter2 = splitter.split("amount=");

    // splitter2[1] will be everything after "amount="
    // if amount= didn't exist it will be undefined
    if(splitter2[1] !== undefined){
        // Now we just split the other side of the amount where &
        // if amount is the last thing and there's no &, it won't matter
        splitter2 = splitter2[1].split("&");

        // Now create the key (l1) and value (splitter2[0])
        actionObject[l1] = splitter2[0];
    }else{
        // If amount is not found, we get id instead, same process
        splitter2 = splitter.split("id=");
        if(splitter2[1] !== undefined){
            splitter2 = splitter2[1].split("&");
            actionObject[l1] = splitter2[0];
        }
    }
}

因此,现在您有了一个对象,actionObject,它包含金额,但仅适用于包含金额或id的值。

actionObject {
    create: "800",
    finalize: "800",
    pay: "14"
}