#javascript #object #key #key-value #creation
#javascript #объект #Клавиша #ключ-значение #создание
Вопрос:
У меня есть такой объект —
const obj = {
'veh1': 'Car',
'veh2': 'Bicycle',
'veh3': 'Truck',
'wheels1': '4',
'wheels2': '2',
'wheels3': '8'
}
Я хочу объект, записи которого отображаются как-
veh1 в wheels1, veh2 в wheels2, veh3 в wheels3 и так далее
Результирующий объект должен быть таким-
const result = {
'Car': '4',
'Bicycle': '2',
'Truck': '8'
}
Я знаю, мы можем сделать это напрямую следующим образом —
{
[obj.veh1]: obj.wheels1,
[obj.veh2]: obj.wheels2,
[obj.veh3]: obj.wheels3
}
Но какой будет лучший способ? Количество записей может быть любым числом ‘n’.
Как я могу достичь этого с помощью javascript?
Комментарии:
1. Перебирайте все ключи объекта, которые начинаются с
veh
, а затем найдите соответствующееwheel
значение.
Ответ №1:
- Создайте записи (пары ключ-значение) из предоставленного объекта.
- Сортируйте записи по каждому ключу записи.
- Наконец, создайте новые объекты из верхней (или левой), а также нижней (или правой) половины ранее отсортированных записей.
function localeCompare(a, b) {
return (a.localeCompare amp;amp; b.localeCompare
amp;amp; a.localeCompare(b))
|| (((a < b) amp;amp; -1) || ((a > b) amp;amp; 1) || 0);
}
function compareEntriesByKey(entryA, entryB) {
return localeCompare(entryA[0], entryB[0]);
}
function createKeyValuePairFromSortedEntryHalfs(obj, $, idx, entries) {
if (((idx 1) % 2) === 0) {
const keyIdx = ((idx - 1) / 2);
const valueIdx = (keyIdx Math.floor(entries.length / 2));
const key = entries[keyIdx][1];
const value = entries[valueIdx][1];
obj[key] = value;
}
return obj;
}
const obj = {
'wheels3': '8',
'veh3': 'Truck',
'wheels1': '4',
'veh1': 'Car',
'wheels2': '2',
'veh2': 'Bicycle',
}
const result = Object
// (1) create entries (key value pairs) from the provided object.
.entries(obj)
// (2) sort the entries by each of an entry's key.
.sort(compareEntriesByKey)
// (3) finally create a new objects from the upper (or left) as
// well the lower (or right) half of the before sorted entries.
.reduce(createKeyValuePairFromSortedEntryHalfs, {});
console.log('result :', result);
console.log('obj', obj);
console.log(
'Object.entries(obj).sort(compareEntriesByKey)',
Object.entries(obj).sort(compareEntriesByKey)
);
console.log(
'proof of being a generic approach...', `
Object.entries({
'foo-biz': 'biz',
'x': 111,
'foo-baz': 'baz',
'y': 222,
'foo-bar': 'bar',
'z': 333,
}).sort(
compareEntriesByKey
).reduce(
createKeyValuePairFromSortedEntryHalfs,
{}
) =>`, Object.entries({
'foo-biz': 'biz',
'x': 111,
'foo-baz': 'baz',
'y': 222,
'foo-bar': 'bar',
'z': 333,
}).sort(
compareEntriesByKey
).reduce(
createKeyValuePairFromSortedEntryHalfs,
{}
)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
Ответ №2:
Вы можете сделать что-то вроде этого:
const vehicles = {};
const wheels = {};
const result = {};
for (key in obj) {
if (key.startsWith("veh")) {
const id = key.replace("veh", "");
vehicles[id] = obj[key];
if (wheels.hasOwnProperty(id)) {
result[vehicles[id]] = wheels[id];
}
} else if (key.startsWith("wheels")) {
const id = key.replace("wheels", "");
wheels[id] = obj[key];
if (vehicles.hasOwnProperty(id)) {
result[vehicles[id]] = wheels[id];
}
}
}
Комментарии:
1. Этот подход работает только для ключей, которые начинаются с или
veh
илиwheels
. Поскольку он должен быть адаптирован к любым изменениям ключевого шаблона объекта, он не является универсальным.2. @PeterSeliger Я предположил, что вопрос задавался для этого конкретного примера, а не общего. Этот подход имеет линейное время выполнения за 1 проход, тогда как для вашего решения требуется 2 прохода и сортировка. Возможно, OP может прояснить их вариант использования.
3. … понял и поддержал. Кстати, ваш подход намного более надежный, чем подход ZaO Lover , потому что последний действительно полагается на точный порядок ключей.
Ответ №3:
const obj = {
'veh1': 'Car',
'veh2': 'Bicycle',
'veh3': 'Truck',
'wheels1': '4',
'wheels2': '2',
'wheels3': '8'
}
let res = {};
let keys = Object.keys(obj);
let i;
for(i = 0; i < keys.length; i ) {
if(keys[i].slice(0, 3) === 'veh') {
res[obj[keys[i]]] = obj[`wheels${keys[i].slice(3)}`];
}
}
console.log(res);
Комментарии:
1. Нельзя полагаться на порядок ключей, особенно если пары ключ-значение не будут предоставлены таким идеальным образом, как в примере кода OP. Общий подход, который в конечном итоге создает новые пары ключ-значение, также не требует никаких предположений о каком-либо из ключей исходного объекта, как это сделано в вашем примере.
2. Мне нравится этот ответ больше, чем мой. Он делает то же самое, но меньше строк. Один вопрос: зачем вам нужно приводить к int?