I need to map some user generated fields to something the system I'm working on can recognize.
For this we want to provide a certain amount of freedom for users, and offer five or so options for each of our fields.
So far we have a switch which does the job, but now we have to extend the switch, and it's going to be pretty big. This is needless to say not a very dynamic way of doing it. Is there any alternatives?
function findHeader(object) {
var title = object.toString().trim().toLowerCase()
switch (title) {
case 'name':
case 'idea':
case 'ide':
case 'ide navn':
case 'title':
case 'idea name':
title = 'name'
break
case 'beskrivelse':
case 'problemet':
case 'description':
case 'the problem':
case 'ide beskrivelse':
title = 'description'
break
case 'ejer':
case 'owner':
case 'opfinder':
case 'ide person':
case 'idea person':
case 'person':
title = 'owner'
break
case 'duedate':
case 'deadline':
case 'tidsfrist':
case 'sidste dato':
case 'dato':
case 'due date':
title = 'duedate'
break
case 'billede':
case 'billeder':
case 'image':
case 'images':
case 'attachment':
title = 'imageUrl'
break
case "":
title = 'remove'
break
default:
title = 'Unassigned'
break
}
return title
}
I need to map some user generated fields to something the system I'm working on can recognize.
For this we want to provide a certain amount of freedom for users, and offer five or so options for each of our fields.
So far we have a switch which does the job, but now we have to extend the switch, and it's going to be pretty big. This is needless to say not a very dynamic way of doing it. Is there any alternatives?
function findHeader(object) {
var title = object.toString().trim().toLowerCase()
switch (title) {
case 'name':
case 'idea':
case 'ide':
case 'ide navn':
case 'title':
case 'idea name':
title = 'name'
break
case 'beskrivelse':
case 'problemet':
case 'description':
case 'the problem':
case 'ide beskrivelse':
title = 'description'
break
case 'ejer':
case 'owner':
case 'opfinder':
case 'ide person':
case 'idea person':
case 'person':
title = 'owner'
break
case 'duedate':
case 'deadline':
case 'tidsfrist':
case 'sidste dato':
case 'dato':
case 'due date':
title = 'duedate'
break
case 'billede':
case 'billeder':
case 'image':
case 'images':
case 'attachment':
title = 'imageUrl'
break
case "":
title = 'remove'
break
default:
title = 'Unassigned'
break
}
return title
}
Share
Improve this question
edited Dec 12, 2018 at 10:55
mplungjan
179k28 gold badges182 silver badges240 bronze badges
asked Dec 12, 2018 at 10:52
Anders JensenAnders Jensen
3295 silver badges21 bronze badges
5
- please add example for the input also – Naor Tedgi Commented Dec 12, 2018 at 10:57
- How about this? stackoverflow./questions/35769144/… – thex Commented Dec 12, 2018 at 10:58
- 2 You can just create a map. You can store it as a separate JSON file if it is dynamic and big. Personally, Personally for me this "certain amount of freedom" sounds more like ambiguity and confusion. Why would someone want to build a service which allows multiple different names for the same thing and creates a fishy map to handle user's invalid data for him. IMHO :) – Yeldar Kurmangaliyev Commented Dec 12, 2018 at 11:00
- We switched to a system where the label is decoupled from the fieldname. So we offer our users only the fieldname: 'name', 'description' and such, and then let them define any label name they want as tied to the standardized name. So kinda like the opposite of your current method. The big advantage is that you don't need to hard code all the different spellings of the same concept, since the user will ad those themselves to the JSON file / database / data store. – Shilly Commented Dec 12, 2018 at 11:16
- There is a really good article about it. – Experimenter Commented Apr 19, 2022 at 20:39
7 Answers
Reset to default 6Perhaps an object?
const titles = {
'name': ['name', 'idea', 'ide', 'ide navn', 'title', 'idea name'],
'description': ['beskrivelse', 'problemet', 'description', 'the problem', 'ide beskrivelse'],
'owner' : ['ejer', 'owner', 'opfinder', 'ide person', 'idea person', 'person'],
'duedate' : ['duedate', 'deadline', 'tidsfrist', 'sidste dato', 'dato', 'due date'],
'imageUrl' : ['billede', 'billeder', 'image', 'images', 'attachment']
}
const getKey = (obj,val) => Object.keys(obj).find(key => obj[key].indexOf(val) !=-1 );
function findHeader(object) {
var title = object.toString().trim().toLowerCase();
return getKey(titles,title) || 'Unassigned'
}
console.log(
findHeader("Owner"),
findHeader("Bla")
)
You can store datas in array of object and search values in it instead of switch
let arr = [
{
"title": "name",
"values": ['idea','ide','ide navn','title','idea name']
},
{
"title": "description",
"values": ['beskrivelse','problemet','description','the problem','ide beskrivelse']
},
{
"title": "owner",
"values": ['ejer','owner','opfinder','ide person','idea person','person']
},
];
function findHeader(object) {
let title = object.toString().trim().toLowerCase(),
res = arr.filter(val => val.values.includes(title));
return res.length ? res[0].title : "Unassigned";
}
console.log(findHeader("problemet"));
console.log(findHeader("ide person"));
console.log(findHeader("opfinderrr"));
You can use a regular expression with an object to get the value of an item based on a string of keys:
const titles = {
"name|idea|ide": "name",
"beskrivelse|problemt|description|the problem": "description"
};
const get_item = item => titles[Object.keys(titles).find(key => new RegExp(`(\\||^)${item}(\\||$)`).test(key))];
let title = "problemt";
title = get_item(title); // Get the associated value from the key
console.log(title);
See this answer for further details.
The solutions others have posted are great and elegant if one expects not too much data.
If performance is crucial and you have huge dictionaries, and/or a lot of terms to replace (order of magnitude 100k or more pieces of data), then your original solution using switch
and case
statements will be the best one, especially if you put the assignment line and the break
statement after every singe case
(making it even uglier). The problem is that you cannot dynamically update that at runtime.
But if dynamic updates is not what you need, you can save this monster of a switch
statement into a separate script file as a function, out of sight, keeping your code tidy.
The point is, while the use of JavaScript objects is much more elegant, I wouldn't pletely discount the switch
& case
solution, depending on the application.