Перевести готовый код (преобразование списка словарей ) с Python на Typescript
Есть входные данные в виде списка словарей. Надо:
- в каждом словаре вытащить значение по одному из ключей
- разбить его по пробелу и взять первую половину
- сделать новый пустой словарь
- строку из п.2 сделать ключом, а значением стартовый словарь из п. 1.
Проще показать, чем объяснять.
Входящие данные.
slots = [
{'qwe': "qwevrtyu", 'asd': "hdf dfgfg", 'zxc': "fjfjwvb"},
{'qwe': "qxcvtyu", 'asd': "hdf mkvfg", 'zxc': "kdkd[vb"},
{'qwe': "bnmrtyu", 'asd': "hdf hskfyweee", 'zxc': "jfjfjfjfb"},
{'qwe': "zxcvtyu", 'asd': "ahfh fhfhf", 'zxc': "lflflflf"},
{'qwe': "qwerbnm", 'asd': "ahfh sgfdhfovppd", 'zxc': "lflflflffff"},
{'qwe': "qwnm", 'asd': "ahfh hfovppd", 'zxc': "lfdddfff"},
{'qwe': "qwerbnm", 'asd': "sgfd dessppd", 'zxc': "lflflflffff"},
{'qwe': "qwerbnm", 'asd': "sgfd qweerpd", 'zxc': "lflflflffff"},
{'qwe': "qwerbnm", 'asd': "sgfd kfkfkfd", 'zxc': "lflflflffff"}
]
Выходящие данные.
[
{'hdf':
[{'qwe': 'qwevrtyu', 'asd': 'hdf dfgfg', 'zxc': 'fjfjwvb'},
{'qwe': 'qxcvtyu', 'asd': 'hdf mkvfg', 'zxc': 'kdkd[vb'},
{'qwe': 'bnmrtyu', 'asd': 'hdf hskfyweee', 'zxc': 'jfjfjfjfb'}]},
{'ahfh':
[{'qwe': 'zxcvtyu', 'asd': 'ahfh fhfhf', 'zxc': 'lflflflf'},
{'qwe': 'qwerbnm', 'asd': 'ahfh sgfdhfovppd', 'zxc': 'lflflflffff'},
{'qwe': 'qwnm', 'asd': 'ahfh hfovppd', 'zxc': 'lfdddfff'}]},
{'sgfd':
[{'qwe': 'qwerbnm', 'asd': 'sgfd dessppd', 'zxc': 'lflflflffff'},
{'qwe': 'qwerbnm', 'asd': 'sgfd qweerpd', 'zxc': 'lflflflffff'},
{'qwe': 'qwerbnm', 'asd': 'sgfd kfkfkfd', 'zxc': 'lflflflffff'}]}
]
Код на Python, работает корректно.
def processSlots(data):
result = []
keys_list = []
for slot in data:
elem_key = slot['asd'].split(" ")[0]
if elem_key in keys_list:
for my_dict in result:
try:
my_dict[elem_key].append(slot)
except KeyError:
pass
else:
my_dict = {}
elem_value = []
my_dict[elem_key] = elem_value
elem_value.append(slot)
result.append(my_dict)
keys_list.append(elem_key)
return [result, keys_list]
Теперь самое главное - надо этот работающий код на Питоне перевести на Typescript. Сделано на ~90%, но на оставшихся 10 % я застрял.
export interface Slot {
qwe: string;
asd: string;
zxc: string;
}
const processSlots = (data: Array<Slot>) => {
interface my_dict_interface {
[key: string]: Array<Slot>
};
const result: Array<my_dict_interface> = [];
const keys_list: string[] = [];
for (let i = 0; i < data.length; i++) {
const slot: Slot = data[i];
const elem_key: string = slot['asd'].split(" ")[0];
let my_dict: my_dict_interface;
if (elem_key in keys_list) {
for (const my_dict in result) {
try {
my_dict[elem_key].add(slot); //Element implicitly has an 'any' type because index expression is not of type 'number'.
}
catch (e: unknown) {
console.log("...ups, i did it again ", e)
}
}
}
else {
const elem_value: Slot[] = []
my_dict[elem_key] = elem_value; // Variable 'my_dict' is used before being assigned.
elem_value.push(slot);
result.push(my_dict); // Variable 'my_dict' is used before being assigned.
keys_list.push(elem_key);
}
}
return [result, keys_list];
}
Выходящие данные должны быть как в примере с Питоном, ну это понятно.
Ответы (3 шт):
Я бы делал иначе.
Cложность O(n^2), где n — количество объектов в массиве slots
Python:
import re
unique_prefixes = set(re.match(r'(\S+)', item['asd']).group(0) for item in slots)
print(unique_prefixes) # {'hdf', 'ahfh', 'sgfd'}
result = {
pref: [item for item in slots if item['asd'].startswith(f'{pref} ')]
for pref in unique_prefixes
}
JavaScript:
const slots = [
{ 'qwe': "qwevrtyu", 'asd': "hdf dfgfg", 'zxc': "fjfjwvb" },
{ 'qwe': "qxcvtyu", 'asd': "hdf mkvfg", 'zxc': "kdkd[vb" },
{ 'qwe': "bnmrtyu", 'asd': "hdf hskfyweee", 'zxc': "jfjfjfjfb" },
{ 'qwe': "zxcvtyu", 'asd': "ahfh fhfhf", 'zxc': "lflflflf" },
{ 'qwe': "qwerbnm", 'asd': "ahfh sgfdhfovppd", 'zxc': "lflflflffff" },
{ 'qwe': "qwnm", 'asd': "ahfh hfovppd", 'zxc': "lfdddfff" },
{ 'qwe': "qwerbnm", 'asd': "sgfd dessppd", 'zxc': "lflflflffff" },
{ 'qwe': "qwerbnm", 'asd': "sgfd qweerpd", 'zxc': "lflflflffff" },
{ 'qwe': "qwerbnm", 'asd': "sgfd kfkfkfd", 'zxc': "lflflflffff" }
];
const uniquePrefixes = new Set(slots.map(item => item.asd.split(' ')[0]));
const result = {};
uniquePrefixes.forEach(prefix => {
result[prefix] = slots.filter(item => item.asd.startsWith(`${prefix} `));
});
console.log(result);
UPD: оптимизация, сложность O(n),
где n — количество объектов в массиве slots
Python:
import re
result = {}
for item in slots:
if match := re.match(r'(\S+)', item['asd']):
if (prefix := match.group(0)) not in result:
result[prefix] = []
result[prefix].append(item)
JavaScript:
const slots = [
{ 'qwe': "qwevrtyu", 'asd': "hdf dfgfg", 'zxc': "fjfjwvb" },
{ 'qwe': "qxcvtyu", 'asd': "hdf mkvfg", 'zxc': "kdkd[vb" },
{ 'qwe': "bnmrtyu", 'asd': "hdf hskfyweee", 'zxc': "jfjfjfjfb" },
{ 'qwe': "zxcvtyu", 'asd': "ahfh fhfhf", 'zxc': "lflflflf" },
{ 'qwe': "qwerbnm", 'asd': "ahfh sgfdhfovppd", 'zxc': "lflflflffff" },
{ 'qwe': "qwnm", 'asd': "ahfh hfovppd", 'zxc': "lfdddfff" },
{ 'qwe': "qwerbnm", 'asd': "sgfd dessppd", 'zxc': "lflflflffff" },
{ 'qwe': "qwerbnm", 'asd': "sgfd qweerpd", 'zxc': "lflflflffff" },
{ 'qwe': "qwerbnm", 'asd': "sgfd kfkfkfd", 'zxc': "lflflflffff" }
];
const result = {};
slots.forEach(item => {
const prefix = item.asd.split(' ')[0];
if (!result[prefix]) {
result[prefix] = [];
}
result[prefix].push(item);
});
console.log(result);
Ну а в TypeScript, Вы сами это реализуете...
Успехов!
Исходный код выдаёт список словарей вместо одного словаря, что противоречит постановке задачи.
Перебираем слоты, для каждого слота вычисляем ключ, если ключа нет, добавляем его в результат, добавляем слот в массив значений:
interface Slot {
qwe: string;
asd: string;
zxc: string;
}
interface Result {
[key: string]: Array<Slot>
}
const processSlots = (slots: Array<Slot>): Result => {
const d: Result = {};
for (const slot of slots) {
const asd = slot.asd;
const key = asd.slice(0, asd.indexOf(' ')); // вычисление ключа
if (!Object.hasOwn(key, d)) { // добавляем ключ в результат
d[key] = [];
}
d[key].push(slot); // добавляем слот в массив
}
return d;
};
var slots = [
{'qwe': "qwevrtyu", 'asd': "hdf dfgfg", 'zxc': "fjfjwvb"},
{'qwe': "qxcvtyu", 'asd': "hdf mkvfg", 'zxc': "kdkd[vb"},
{'qwe': "bnmrtyu", 'asd': "hdf hskfyweee", 'zxc': "jfjfjfjfb"},
{'qwe': "zxcvtyu", 'asd': "ahfh fhfhf", 'zxc': "lflflflf"},
{'qwe': "qwerbnm", 'asd': "ahfh sgfdhfovppd", 'zxc': "lflflflffff"},
{'qwe': "qwnm", 'asd': "ahfh hfovppd", 'zxc': "lfdddfff"},
{'qwe': "qwerbnm", 'asd': "sgfd dessppd", 'zxc': "lflflflffff"},
{'qwe': "qwerbnm", 'asd': "sgfd qweerpd", 'zxc': "lflflflffff"},
{'qwe': "qwerbnm", 'asd': "sgfd kfkfkfd", 'zxc': "lflflflffff"}
]
var res = Object.create(null)
for (var x of slots) {
(res[x.asd.split(" ")[0]] ||= []).push(x)
}
console.log(res)
.as-console-wrapper.as-console-wrapper {
max-height: 100vh;
}
На ts почти так же: playground
var slots: ({ [key in string]?: string } & { asd: string })[] = [
{'qwe': "qwevrtyu", 'asd': "hdf dfgfg", 'zxc': "fjfjwvb"},
{'qwe': "qxcvtyu", 'asd': "hdf mkvfg", 'zxc': "kdkd[vb"},
{'qwe': "bnmrtyu", 'asd': "hdf hskfyweee", 'zxc': "jfjfjfjfb"},
{'qwe': "zxcvtyu", 'asd': "ahfh fhfhf", 'zxc': "lflflflf"},
{'qwe': "qwerbnm", 'asd': "ahfh sgfdhfovppd", 'zxc': "lflflflffff"},
{'qwe': "qwnm", 'asd': "ahfh hfovppd", 'zxc': "lfdddfff"},
{'qwe': "qwerbnm", 'asd': "sgfd dessppd", 'zxc': "lflflflffff"},
{'qwe': "qwerbnm", 'asd': "sgfd qweerpd", 'zxc': "lflflflffff"},
{'qwe': "qwerbnm", 'asd': "sgfd kfkfkfd", 'zxc': "lflflflffff"}
]
var res: { [key in string]?: (typeof slots)[number][] } = Object.create(null)
for (var x of slots) {
(res[x.asd.split(" ")[0]] ||= []).push(x)
}
console.log(res)