使用map / reduce / filter优化Javascript脚本

时间:2019-09-03 08:28:58

标签: javascript

这是我的问题,我收到这类json数据,但我事先不知道键(unknownProperty#),但是此数据数组中的不同对象具有相同的键。我需要做的是计算每个警报级别的数量(这些级别是固定的)。 这是我的最终结果应该是什么

var result = { unknownProperty1: { unknown: 0, ok: 2, warning: 0, ko: 1 },
  unknownProperty2: { unknown: 0, ok: 0, warning: 2, ko: 1 },
  unknownProperty3: { unknown: 3, ok: 0, warning: 0, ko: 0 },
  unknownProperty4: { unknown: 0, ok: 0, warning: 3, ko: 0 },
  unknownProperty5: { unknown: 0, ok: 0, warning: 2, ko: 1 } }

我的脚本正在运行,但是我想知道是否有任何方法可以使用map / reduce / filter javascript函数对其进行优化/清理

const data = [
  {
    unknownProperty1: { alert: "ok", unusedItem1: "something" },
    unknownProperty2: { alert: "warning", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "ko", unusedItem1: "something" }
  },
  {
    unknownProperty1: { alert: "ok", unusedItem1: "something" },
    unknownProperty2: { alert: "warning", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "warning", unusedItem1: "something" }
  },
  {
    unknownProperty1: { alert: "ko", unusedItem1: "something" },
    unknownProperty2: { alert: "ko", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "warning", unusedItem1: "something" }
  }
];

var result = new Object();
var dataKeys = data.map(function(element) {
  return Object.keys(element);
});
dataKeys[0].map(function(element) {
  result[element] = { unknown: 0, ok: 0, warning: 0, ko: 0 };
});
//At this point the result is like what we expect but no calculation has been made yet

//We then increment the right values
data.map(function(element) {
  for (var prop in element) {
    if (Object.prototype.hasOwnProperty.call(element, prop)) {
      // element correspond to the current object
      // prop corresponds to the name of the key, for example 'unknownProperty1'
      switch (element[prop].alert) {
        case "ok":
          result[prop].ok++;
          break;
        case "warning":
          result[prop].warning++;
          break;
        case "unknown":
          result[prop].unknown++;
          break;
        case "ko":
          result[prop].ko++;
          break;

        default:
          break;
      }
    }
  }
});
console.log(result);

3 个答案:

答案 0 :(得分:6)

简化为用unknownProperty_键索引的对象,迭代内部对象,并在累加器上创建合适的键(如果尚不存在),并将其值设置为{ unknown: 0, ok: 0, warning: 0, ko: 0 }。然后,在unknownProperty对象上的每次迭代中,只需提取alert并递增a[key][alert]

const data = [
  {
    unknownProperty1: { alert: "ok", unusedItem1: "something" },
    unknownProperty2: { alert: "warning", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "ko", unusedItem1: "something" }
  },
  {
    unknownProperty1: { alert: "ok", unusedItem1: "something" },
    unknownProperty2: { alert: "warning", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "warning", unusedItem1: "something" }
  },
  {
    unknownProperty1: { alert: "ko", unusedItem1: "something" },
    unknownProperty2: { alert: "ko", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "warning", unusedItem1: "something" }
  }
];

const dataByProperty = data.reduce((a, obj) => {
  Object.entries(obj).forEach(([key, { alert }]) => {
    if (!a[key]) {
      a[key] = { unknown: 0, ok: 0, warning: 0, ko: 0 };
    }
    a[key][alert]++;
  });
  return a;
}, {});
console.log(dataByProperty);

答案 1 :(得分:1)

也许有点晚,但这是我的类似想法:

(注意:避免使用let obj = new Object();,而应使用let obj = {}


const data = [
    {
        unknownProperty1: { alert: "ok", unusedItem1: "something" },
        unknownProperty2: { alert: "warning", unusedItem1: "something" },
        unknownProperty3: { alert: "unknown", unusedItem1: "something" },
        unknownProperty4: { alert: "warning", unusedItem1: "something" },
        unknownProperty5: { alert: "ko", unusedItem1: "something" }
    },
    {
        unknownProperty1: { alert: "ok", unusedItem1: "something" },
        unknownProperty2: { alert: "warning", unusedItem1: "something" },
        unknownProperty3: { alert: "unknown", unusedItem1: "something" },
        unknownProperty4: { alert: "warning", unusedItem1: "something" },
        unknownProperty5: { alert: "warning", unusedItem1: "something" }
    },
    {
        unknownProperty1: { alert: "ko", unusedItem1: "something" },
        unknownProperty2: { alert: "ko", unusedItem1: "something" },
        unknownProperty3: { alert: "unknown", unusedItem1: "something" },
        unknownProperty4: { alert: "warning", unusedItem1: "something" },
        unknownProperty5: { alert: "warning", unusedItem1: "something" }
    }
];

let result = data.reduce((acc, val) => {
    for (let i in val) {
        if (!val.hasOwnProperty(i)) {
            continue;
        }
        acc[i] || (acc[i] = {unknown: 0, ok: 0, warning: 0, ko: 0});
        acc[i][val[i].alert]++;
    }
    return (acc);
}, {});

console.log(result);

答案 2 :(得分:1)

迟到了,但这是另一个例子,

完整代码(请参阅console.log):https://stackblitz.com/edit/js-5rnwvv

输入数据:

const data = [
  {
    unknownProperty1: { alert: "ok", unusedItem1: "something" },
    unknownProperty2: { alert: "warning", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "ko", unusedItem1: "something" }
  },
  {
    unknownProperty1: { alert: "ok", unusedItem1: "something" },
    unknownProperty2: { alert: "warning", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "warning", unusedItem1: "something" }
  },
  {
    unknownProperty1: { alert: "ko", unusedItem1: "something" },
    unknownProperty2: { alert: "ko", unusedItem1: "something" },
    unknownProperty3: { alert: "unknown", unusedItem1: "something" },
    unknownProperty4: { alert: "warning", unusedItem1: "something" },
    unknownProperty5: { alert: "warning", unusedItem1: "something" }
  }
];

用于输出数据的代码:

const a = data.reduce((acc, x, i) => {
  const keys = Object.keys(x);
  keys.forEach((key, j) => {
    const childKey = Object.keys(x[key])[0]; // only 'alert' key needed
    if (acc.hasOwnProperty(keys[j])) {
      // update existing key value pair
      ++acc[key][x[key][childKey]]
    } else {
      // add key value pair for the first time
      acc = {
        ...acc,
        [keys[j]]:
          ['unknown', 'warning', 'ko', 'ok'].reduce((ac, z) => ({ ...ac, [z]: x[key][childKey] === z ? 1 : 0 }), {})
      }
    }

  })
  return acc;

}, {})