У меня есть следующий массив объектов:
[
{
"job_id": 1,
"job_name": "Engineer"
},
{
"job_id": 2,
"job_name": "Scientist"
},
{
"job_id": 3,
"job_name": "Teacher"
}
]
где следующий код используется для создания Material-UI Select - параметры вот вышеупомянутый массив объектов:
{options.map(option => {
return (
<MenuItem key = {option.job_id} value = {option.job_id}>
{option.job_name}
</MenuItem>
)
})}
Мои вопросы заключаются в том, чтобы не связывать его с фактическими именами ключей option.job_id и option.job_name, поскольку я смотрю на использование разных наборов данных с разными именами ключей, но всегда следуя этому формату пары значений ключа - можно ли изменить функцию карты, чтобы сделать это более общий, чтобы не беспокоиться об именах ключей, но по-прежнему возвращать данные для раскрывающегося списка Select, то есть:
{options.map(option => {
return (
<MenuItem key = {option.generic_id} value = {option.generic_id}>
{option.generic_name}
</MenuItem>
)
})}
Думаю, я спрашиваю, можно ли получить доступ к ключам объекта через функцию карты без необходимости знать job_id и job_name?
Думаю, я спрашиваю, можно ли получить доступ к ключам объекта через функцию карты без необходимости знать job_id и job_name. Надеюсь, это имеет смысл?
@NearHuscarl - правильно.
Вам необходимо знать конкретные имена ключей где-нибудь в процессе обработки.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если вы хотите иметь возможность использовать ключи динамических объектов, похоже, вам нужна какая-то вспомогательная функция, которая может принимать массив и соответствующие ключи и возвращать ваши пункты меню.
Например
const menuBuilder = (options, keyProp, labelProp) => options.map(option => (
<MenuItem key = {option[keyProp]} value = {option[keyProp]}>
{option[labelProp]}
</MenuItem>
))
Обратной стороной такого подхода я вижу то, что в кодовой базе должно быть место, которое знает и о job_id, и о <MenuItem>. Его легко читать, но он решает проблему, увеличивая площадь поверхности и делая конструкцию более жесткой.
Если вы не можете сделать ключи более общими в восходящем направлении, вы можете сделать одно из двух
import { pipe, mapKeys } from 'utils';
const normaliseOption = mapKeys(key =>
key.match(/_id$/) ? 'id'
: key.match(/_name$/) ? 'name'
: key
);
options.map(pipe(normaliseOption, option =>
<MenuItem key = {option.id} value = {option.id}>
{option.name}
</MenuItem>
));
// utils
export const pipe = (...fns) => fns.reduce(
(f, g) => x => g(f(x))
);
export const mapKeys = f => pipe(
Object.entries,
x => x.map(([k, v]) => [f(k), v]),
Object.fromEntries
);
1.bis) Где-то в апстриме, где вы точно знаете, что имеете дело с заданиями, вы можете сделать это без регулярного выражения.
options.map(option =>
<MenuItem key = {option.getId()} value = {option.getId()}>
{option.getName()}
</MenuItem>
);
// somewhere you know you are dealing with jobs
import JobOption from './JobOption';
const options = jobs.map(JobOption.of);
export default class JobOption {
constructor({job_id, job_name}) {
this.id = job_id;
this.name = job_name;
}
static of (descriptor) { return new JobOption(descriptor); }
getId () { return this.id; }
getName () { return this.name; }
}
Непонятно, о чем вы спрашиваете. Вы хотите изменить массив, чтобы изменить ключи объекта, или вы спрашиваете о чем-то другом?