将字符串重新格式化为可行的数据格式

时间:2019-02-15 20:03:09

标签: javascript arrays object

我有一个字符串数组,我正在寻找一种更好的方法将以下数据重新格式化为可行的格式

const list = ["Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2019, 1:15 PM", "Record - Name: Peter - Salary: 120000 - Position: Accountant - Date: February 15, 2019, 1:15 PM", "Record - Name: Jonny - Salary: 90000 - Position: Developer - Date: February 15, 2019, 1:15 PM", "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2019, 1:15 PM"]

这就是我需要的:

  • 仔细检查每个字符串并删除重复的字符串,只保留Salary较高的字符串
  • 将它们变成对象/数组,以便以后可以在object.name
  • 上访问每个属性

到目前为止,这是我可以使用的,但是可以,但是我希望有更好的方法吗?

const list = [
  "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2018, 1:15 PM",
  "Record - Name: Peter - Salary: 120000 - Position: Accountant - Date: February 15, 2019, 1:15 PM",
  "Record - Name: Jonny - Salary: 90000 - Position: Developer - Date: February 15, 2019, 1:15 PM",
  "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2018, 1:15 PM"
];

const newList = list.map(donation => {
  const a = donation.split(' - ');
  const name = a[1].split(': ')[1];
  const salary = a[2].split(': ')[1];
  const position = a[3].split(': ')[1];
  const date = a[4].split(': ')[1];
  return { name, salary, position, date };
});

console.log('newList: \n', JSON.stringify(newList, null, 4));
console.log("\n");

let obj = {};
newList.forEach(current => {
  let index = current['name'];
  if (obj[index]) {
    if (obj[index]['name'] === current['name']) {
      if (+obj[index]['salary'] < +current['salary']) {
        obj[index] = current;
      }
    }
  } else {
    obj[index] = current;
  }
})

console.log('Result: \n', JSON.stringify(obj, null, 4));

3 个答案:

答案 0 :(得分:0)

您可以使用mapreduce首先创建对象数组,然后再使用reduce获取每个名称的最高薪水对象。

const list = [
  "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2018, 1:15 PM",
  "Record - Name: Peter - Salary: 120000 - Position: Accountant - Date: February 15, 2019, 1:15 PM",
  "Record - Name: Jonny - Salary: 90000 - Position: Developer - Date: February 15, 2019, 1:15 PM",
  "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2018, 1:15 PM"
];

const data = list.map(rec => {
  return rec.replace(/ /g, '').split('-').slice(1)
    .reduce((r, e) => {
      let [key, value] = e.split(':')
      r[key.toLowerCase()] = value
      return r;
    }, {})
})

const filtered = data.reduce((r, e) => {
  if (!r[e.name]) r[e.name] = e;
  else if (r[e.name].salary < e.salary) r[e.name] = e
  return r
}, {})

console.log(Object.values(filtered))

答案 1 :(得分:0)

我可能会这样写:

const recToObj = rec => rec.split(/\s*-\s*/).slice(1).reduce((o, p) => {
  const [k, v] = p.split(/:\s*/)
  return {...o, [k]: v}
}, {})

const higherSalary = (a, b) => a ? a.Salary > b.Salary ? a : b : b

const listToObj = (records) => {
  const objs = records.map(recToObj)
  return objs.reduce((o, v) => ({...o, [v.Name]: higherSalary(o[v.Name], v)}), {})
}

const list = [
  "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2018, 1:15 PM",
  "Record - Name: Peter - Salary: 120000 - Position: Accountant - Date: February 15, 2019, 1:15 PM",
  "Record - Name: Jonny - Salary: 90000 - Position: Developer - Date: February 15, 2019, 1:15 PM",
  "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2018, 1:15 PM"
];

console.log(listToObj(list))

请注意,由于字符串中存在初始recToObj令牌,因此"Record"的通用性比我们期望的要差一些。但这至少允许您添加更多字段而无需在问题中一次性完成。


如果Haskell对Javascript实施空白禁运,我可能会这样写:

const recToObj = rec => rec.split(/\s*-\s*/).slice(1).reduce((o, p, _, $, [k, v] = p.split(/:\s*/)) => ({...o, [k]: v}), {})
const higherSalary = (a, b) => a ? a.Salary > b.Salary ? a : b : b
const listToObj = (rs) => rs.map(recToObj).reduce((o, v) => ({...o, [v.Name]: higherSalary(o[v.Name], v)}), {})

:-)

答案 2 :(得分:0)

通过使用Array#from,Array#reduce,String#split,String#match,解构,传播语法和正则表达式,您可以执行类似的操作。

const data = [
  "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2018, 1:15 PM",
  "Record - Name: Peter - Salary: 120000 - Position: Accountant - Date: February 15, 2019, 1:15 PM",
  "Record - Name: Jonny - Salary: 90000 - Position: Developer - Date: February 15, 2019, 1:15 PM",
  "Record - Name: Peter - Salary: 100000 - Position: Accountant - Date: February 15, 2018, 1:15 PM"
];

const res = Array.from(
  data.reduce((m,str)=>{
    const {Name, Salary, ...rest} = str
      .match(/(?![Record])(\w+\s*:((\s|,|:)*\w|\d)+)/g)
      .reduce((a,c)=>{
        const [k,v] = c.split(/:\s?(?!\d)/)
        a[k] = v;
        return a;
      }, {});

    const record = m.get(Name);
    if(!record ||record.Salary < Salary) return m.set(Name, {Name, Salary, ...rest});
    else return m;
  }, new Map()).values()
);

console.log(res);