добавление функции в циклы - PullRequest
0 голосов
/ 05 мая 2019

Мне нужно искать в большой json-коллекции с рекурсивным уникальным идентификатором. Коллекция содержит значения ключей или вложенные массивы, которые содержат ключи. Ключи могут быть в любом месте объекта. Ключи могут быть числовыми или строковыми.

Обратите внимание: значения ключей являются уникальными, если они не находятся в массиве. Если они находятся в массиве, ключ дублируется на элементы в массиве. Например,

"WebData": {
      WA1: 3, //not in array so unique
      WA3: 2, so unique
      WA3: "NEO",
      WebGroup : [
    { Web1: 1, //duplicate Web1
              Web2: 2
            },
            { Web1: 2, //duplicate Web2
              Web2: 2
            }]
     }

Что я хочу: Я передам массив ключей в разных вариациях, например

  1. Не в массивах: я передам ключу возврат либо их значения, либо сумму, например:
function(["WA1",""WA3", "RAE1"],"notsum")

Если я сдам (не сумма)

["WA1",""WA3", "RAE1"]

и операция не является "суммой", она должна возвращать массив их значений из коллекции

[3,2,1]

Если я пройду то же самое, но операция будет суммой)

function(["WA1",""WA3", "RAE1"],"sum")

["WA1",""WA3", "RAE1"]

должна вернуть сумму из коллекции

return 6
  1. Если в массиве: если значение для поиска находится в массиве, означает, что они дублируются, то он должен вернуть мне сумму или их отдельные значения снова. Например,
["WEB1","Web2"]

. Это может либо вернуть меня,

[7,1]  //Again total of 3+4, 0+1 //see in example

или

[[3,4],[0,1]]  //Because values are duplicate and in array, just collect them

Мне нужно сделать элегантно:

Полный пример JSON:

{
  version: "1.0"
  submission : "editing"
  "WebData": {
          WA1: 3,
          WA3: 2,  
          WA3: "NEO",
          WebGroup : [
        { Web1: 3,
                  Web2: 0
                },
                { Web1: 4,
                  Web2: 1
                }]
  },
  "NonWebData": {
          NWA1: 3,
          NWA2: "INP",
          NWA3: 2,  
  },
  "FormInputs": {
          FM11: 3,
          FM12: 1,
          FM13: 2,

  "RawData" : {
     "RawOverview": {
            "RAE1" : 1,
            "RAE2" : 1,
     },
     "RawGroups":[
                 {
                 "name": "A1",
                 "id":   "1",
                 "data":{
                         "AD1": 'period',
                         "AD2": 2,
                         "AD3": 2,                        
                         "transfers": [
                                       {
                                            "type": "in",
                                            "TT1": 1,
                                            "TT2": 2,
                                       },
                                       {
                                            "type": "out",
                                            "TT1": 1,
                                            "TT2": 2,
                                       }
                ]
                           }
                  },
                 {
                 "name": "A2",
                 "id":   "2",
                 "data":{
                         "AD1": 'period',
                         "AD2": 2,
                         "AD3": 2,                        
                         "transfers": [
                                       {
                                            "type": "in",
                                            "TT1": 1,
                                            "TT2": 2,
                                       },
                                       {
                                            "type": "out",
                                            "TT1": 1,
                                            "TT2": 2,
                                       }
                ]
                           }
                  }
               ]
             },
            "Other":
               { O1: 1,
                 O2: 2,
                 O3: "hello"
               },
            "AddedBy": "name"
            "AddedDate": "11/02/2019"
         }

Я не могу написать здесь функцию, которая может сделать это для меня, мой код просто ищет в этом массиве, и я перебираю, чтобы найти его, что, я уверен, не правильный путь.

Мой код не элегантный, и я использую как-то повторяющиеся функции. Это всего лишь один фрагмент, чтобы узнать ключи на одном уровне. Я хочу, чтобы все это делали только 1 или 2 функции

function Search(paramKey, formDataArray) {
    var varParams = [];
    for (var key in formDataArray) {
        if (formDataArray.hasOwnProperty(key)) {
            var val = formDataArray[key];
            for (var ikey in val) {
                if (val.hasOwnProperty(ikey)) {
                    if (ikey == paramKey)
                        varParams.push(val[ikey]);
                }
            }
        }
    }
    return varParams;
}
  1. Еще один тестовый случай, если в Array: Возвращать только один массив значений, без добавления. (Обновление - я добился этого, отредактировав код следующей части)
 notsumsingle: function (target, key, value) {
                if (target[key] === undefined) {
                    target[key] = value;
                    return;
                }
                target.push(value);
            },

"groupData": [
            {
                "A1G1": 1,
                "A1G2": 22,
                "AIG3": 4,
                "AIG4": "Rob"
            },
            {
                "A1G1": 1,
                "A1G2": 41,
                "AIG3": 3,
                "AIG4": "John"
            },
            {
                "A1G1": 1,
                "A1G2": 3,
                "AIG3": 1,
                "AIG4": "Andy"
              }
        ],

execute (["AIG2", "" AIG4 "]," notsum ")

Возвращает меня

[
    [
        22,
        41,
        3
    ]
],
[
    [
        "",
        "Ron",
        "Andy"
    ]
]

Вместо этого я могу добавить еще одну вариацию «SingleArray», например «sum» и «notsum», и получить результат в виде одного массива.

    [
        22,
        41,
        3
    ]

    [
        "",
        "Ron",
        "Andy"
    ]     

Четвертый, я спросил, возможно ли, чтобы функция была достаточно умной, чтобы автоматически подбирать сумму массивов или сумму отдельных полей. например, в вашем примере вы использовали «sum» и «total», чтобы идентифицировать это.

console.log(perform(["WA1", "WA3", "RAE1"], "total"));  // 6
console.log(perform(["Web1", "Web2"], "sum"));          // [7, 1]

Может ли функция, просто использовать "sum" и возвращать одиночное или массив на основе, если найдет массив, вернуть [7,1], если не вернуть, 6

5th: Я обнаружил проблему в коде, если коллекция json добавлена ​​таким образом

perform(["RAE1"], "notsum") //[[1,1]]
perform(["RAE1"], "sum")  //2

Возвращает [1, 1] или 2, хотя определен только один RAE1, и обратите внимание, что это не массив [], поэтому его не следует кодировать в массив [[]], просто ключ объекта

 "RawData" : {
 "RawOverview": {
        "RAE1" : 1,
        "RAE2" : 1,
 }

1 Ответ

0 голосов
/ 05 мая 2019

Чтобы упростить задачу и использовать один и тот же интерфейс для получения сумм или не сумм и итогов, без какого-либо массива, вы можете ввести другую строку операции total для получения суммы всех ключей.

Этот подход использует объект для получения функции, которая либо добавляет значение в массив с тем же индексом, либо сохраняет значение по указанному индексу, который соответствует указанному массиву ключей функции.

Для итерации объекта вы можете взять пары ключ / значение и выполнять итерацию до тех пор, пока объект не будет найден.

В результате вы получите массив или общую сумму всех элементов.

Кстати, ключи объекта чувствительны к регистру, например 'WEB1' не соответствует 'Web1'.

function perform(keys, operation) {
    function visit(object) {
        Object
            .entries(object)
            .forEach(([k, v]) => {
                if (k in indices) return fn(result, indices[k], v);
                if (v && typeof v === 'object') visit(v);
            });
    }

    var result = [],
        indices = Object.assign({}, ...keys.map((k, i) => ({ [k]: i }))),
        fn = {
            notsum: function (target, key, value) {
                if (target[key] === undefined) {
                    target[key] = value;
                    return;
                }
                if (!Array.isArray(target[key])) {
                    target[key] = [target[key]];
                }
                target[key].push(value);
            },
            sum: function (target, key, value) {
                target[key] = (target[key] || 0) + value;
            }
        }[operation === 'total' ? 'sum' : operation];

    visit(data);
    return operation === 'total'
        ? result.reduce((a, b) => a + b)
        : result;
}

var data = { version: "1.0", submission: "editing", WebData: { WA1: 3, WA3: 2, WAX: "NEO", WebGroup: [{ Web1: 3, Web2: 0 }, { Web1: 4, Web2: 1 }] }, NonWebData: { NWA1: 3, NWA2: "INP", NWA3: 2 }, FormInputs: { FM11: 3, FM12: 1, FM13: 2 }, RawData: { RawOverview: { RAE1: 1, RAE2: 1 }, RawGroups: [{ name: "A1", id: "1", data: { AD1: 'period', AD2: 2, AD3: 2, transfers: [{ type: "in", TT1: 1, TT2: 2 }, { type: "out", TT1: 1, TT2: 2 }] } }, { name: "A2", id: "2", data: { AD1: 'period', AD2: 2, AD3: 2, transfers: [{ type: "in", TT1: 1, TT2: 2 }, { type: "out", TT1: 1, TT2: 2 }] } }] }, Other: { O1: 1, O2: 2, O3: "hello" }, AddedBy: "name", AddedDate: "11/02/2019" };

console.log(perform(["WA1", "WA3", "RAE1"], "notsum")); // [3, 2, 1]
console.log(perform(["WA1", "WA3", "RAE1"], "total"));  // 6
console.log(perform(["Web1", "Web2"], "sum"));          // [7, 1]
console.log(perform(["Web1", "Web2"], "notsum"));       // [[3, 4], [0, 1]]
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...