агрегированная сумма на основе ключей в javascript

#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. Миллион благодарностей, Нина, всего наилучшего!