#javascript
#javascript
Вопрос:
У меня есть массив объектов, который выглядит следующим образом
var data = [];
data[0] = {'TrueDestination': 'EU.UK.London', 'EU.UK.London':5, 'EU.UK.Bath':4, 'EU.France.Lyon':1, 'EU.France.Paris':0, 'Asia.Japan.Tokyo':4},
data[1] = {'TrueDestination': 'EU.UK.Bath', 'EU.UK.London':7, 'EU.UK.Bath':1, 'EU.France.Lyon':8, 'EU.France.Paris':0, 'Asia.Japan.Tokyo':1},
data[2] = {'TrueDestination': 'EU.France.Paris', 'EU.UK.London':2, 'EU.UK.Bath':2, 'EU.France.Lyon':2, 'EU.France.Paris':6, 'Asia.Japan.Tokyo':3},
data[3] = {'TrueDestination': 'EU.France.Lyon', 'EU.UK.London':9, 'EU.UK.Bath':0, 'EU.France.Lyon':1, 'EU.France.Paris':0, 'Asia.Japan.Tokyo':2},
data[4] = {'TrueDestination': 'EU.France.Lyon', 'EU.UK.London':2, 'EU.UK.Bath':4, 'EU.France.Lyon':3, 'EU.France.Paris':7, 'Asia.Japan.Tokyo':7},
Я хотел бы
- примените функцию к ключам моих объектов в моих данных, чтобы я мог удалять строки, разделенные точками. Так, например, удалите
London
илиUK.London
изEU.UK.London
, но неUK
изUK.London
или изEU.UK.London
. (Добавлено после комментария Т.Дж. Краудера ниже: чтобы избежать путаницы, вы удаляете движение назад) - Затем для каждого объекта взять агрегированную сумму, сгруппированную по ключу
Например, если я удаляю город, последний бит в ключевых строках, я хочу получить массив
var data = [];
data[0] = {'TrueDestination': 'EU.UK', 'EU.UK':9, 'EU.France':1, 'Asia.Japan':4},
data[1] = {'TrueDestination': 'EU.UK', 'EU.UK':8, 'EU.France':8, 'Asia.Japan':1},
data[2] = {'TrueDestination': 'EU.France', 'EU.UK':4, 'EU.France':8, 'Asia.Japan':3},
data[3] = {'TrueDestination': 'EU.France', 'EU.UK':9, 'EU.France':1, 'Asia.Japan':2},
data[4] = {'TrueDestination': 'EU.France', 'EU.UK':6, 'EU.France':10, 'Asia.Japan':7},
Я написал это, чтобы удалить ключи
function stripper(d, k){
// k controls how many times you want to strip the string
for (i=0; i<k; i){
if (d.lastIndexOf('.') > 0){
d = d.substring(0, d.lastIndexOf('.'))
}
}
return d
}
но моя функция работы с ключами — настоящее затруднение. (и это не работает!) В любом случае, это то, где я нахожусь до сих пор
stripLevel = 1
columnNames = data.columns.map(d => stripper(d, stripLevel))
for (j=0; j<columnNames.length; j){
cname = columnNames[j];
for (i=0; i<data.length; i) {
var _obj = {}
obj = data[i]
_keys = Object.keys(obj)
total = 0
for (k = 0; k < _keys.length; k) {
cur = _keys[k]
if ((cname != 'model_class') amp;amp; (stripper(cur, stripLevel) === cname)) {
total = parseFloat(obj[cur])
}
_objTemp = {[stripper(cur, stripLevel)]: total}
Object.assign(_obj, _objTemp)
total = 0
}
}
}
Любая помощь с благодарностью
Комментарии:
1. «примените функцию к ключам моих объектов в моих данных, чтобы я мог удалять строки, разделенные точками. Так, например, удалите Лондон или Великобританию. Лондон из EU.UK.London, но не Великобритания из Великобритании. Лондон или из EU.UK.London» Каковы правила для принятия решения о том, что удаляется, а что нет? Правила кажутся … странными…
2.«… но не UK из Великобритании.Лондон или из EU.UK.London …» Должна ли она как-то
EU
добавляться кUK.London
? Если да, то каким образом?3. Допустим, вы удаляете движение назад, от конца к началу. Или, если это прояснит ситуацию, вы удаляете сначала город, а затем страну
Ответ №1:
Вы могли бы создать новый объект и добавить значения одного и того же ключа.
Она работает с записями объекта и деструктурированной парой ключ/ значение k
/ v
и функцией для получения первых частей пунктирных строк и проверки ключа.
Если ключ k
равен TrueDestination
, то он принимает неизмененный ключ и присваивает ему измененное значение. во всех остальных случаях он принимает значение свойства с новым ключом или нулем, добавляет значение и присваивает сумму свойству.
Наконец, объект возвращается.
var data = [{ TrueDestination: 'EU.UK.London', 'EU.UK.London': 5, 'EU.UK.Bath': 4, 'EU.France.Lyon': 1, 'EU.France.Paris': 0, 'Asia.Japan.Tokyo': 4 }, { TrueDestination: 'EU.UK.Bath', 'EU.UK.London': 7, 'EU.UK.Bath': 1, 'EU.France.Lyon': 8, 'EU.France.Paris': 0, 'Asia.Japan.Tokyo': 1 }, { TrueDestination: 'EU.France.Paris', 'EU.UK.London': 2, 'EU.UK.Bath': 2, 'EU.France.Lyon': 2, 'EU.France.Paris': 6, 'Asia.Japan.Tokyo': 3 }, { TrueDestination: 'EU.France.Lyon', 'EU.UK.London': 9, 'EU.UK.Bath': 0, 'EU.France.Lyon': 1, 'EU.France.Paris': 0, 'Asia.Japan.Tokyo': 2 }, { TrueDestination: 'EU.France.Lyon', 'EU.UK.London': 2, 'EU.UK.Bath': 4, 'EU.France.Lyon': 3, 'EU.France.Paris': 7, 'Asia.Japan.Tokyo': 7 }],
result = data.map(o => Object.entries(o).reduce((o, [k, v]) => {
const firsts = k => k.split('.').slice(0, -1).join('.');
if (k === 'TrueDestination') {
o[k] = firsts(v);
} else {
k = firsts(k);
o[k] = (o[k] || 0) v;
}
return o;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Комментарии:
1. Большое спасибо, Нина, это работает как шарм. Не могли бы вы вкратце описать, как это работает, пожалуйста? Я пытаюсь разобраться в map reduce, но мне не удалось справиться с этим….
2. Вы также думаете, что что-то подобное можно использовать для вычисления медианы вместо суммы, пожалуйста? Я полагаю, что для этого потребуется каким-то образом собрать все значения в массив, возможно, и в конце отсортировать их и выбрать среднюю точку. Я не прошу вас писать это, просто если вы считаете, что это выполнимо, и подсказка о том, как следует действовать. Еще раз спасибо!
3. для медианы вам нужен массив и, наконец, выберите значение или среднее из средних значений отсортированного массива. для получения среднего значения вам нужны сумма и количество и, наконец, возьмите результат деления. в этом случае у вас есть двухэтапная итерация, одна для объектов, а другая для ключей / значений. после итерации ключа / значения вы могли бы вернуть желаемую медиану (действительно?) или среднее значение.
4. Миллион благодарностей, Нина, всего наилучшего!