J'ai un tableau de chaînes, je recherche un meilleur moyen de reformater les données suivantes dans un format exploitable
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));Voici ce dont j'ai besoin:
Salary object.name C'est ce que j'ai jusqu'à présent, cela fonctionne, mais j'espère qu'il y a une meilleure façon de faire cela?
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"]
3 Réponses :
Vous pouvez utiliser map et reduction pour créer d'abord un tableau d'objets, puis une autre réduction pour obtenir le meilleur objet de salaire pour chaque nom.
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))
Je pourrais écrire quelque chose comme ceci:
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)}), {})
Notez que recToObj est un peu moins générique que nous pourrions l'espérer en raison de la présence du jeton initial "Record" dans les chaînes. Mais cela vous permet au moins d'ajouter plus de champs sans faire les one-offs dans la question.
Et si Haskell imposait un embargo sur les espaces blancs sur Javascript, je pourrais l'écrire comme ceci:
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)):-)
Vous pouvez faire quelque chose comme ceci, en utilisant Array # from, Array # reduction, String # split, String # match, destructuring, spread syntax and regex.
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);
définir «meilleure façon»?