代码之家  ›  专栏  ›  技术社区  ›  Code Guy

通过迭代JSON的所有对象来获取数组值的最大值

  •  0
  • Code Guy  · 技术社区  · 4 年前

    我有一个JSON,需要获取最大数量的单个最大值。下面的代码显示每个项目的最大值,但我需要得到所有项目的最大值。这里预期的答案是78

    for(var x in items) {
      console.log("Max is" + Math.Max(items[x]));
    }
    
    
    var items = {
        "title": "Find Max",
        "A": [0, 78],
        "Z": [1],
        "R": [2, 10],
        "N": [2, 10, 56],
        "P": [5, 56]
    }
    
    2 回复  |  直到 4 年前
        1
  •  3
  •   Nick SamSmith1986    4 年前

    你可以用 Object.values Array.isArray ),然后使用 Array.reduce 要查找所有数组的最大值,请执行以下操作:

    var items = {
      "title": "Find Max",
      "A": [0, 78],
      "Z": [1],
      "R": [2, 10],
      "N": [2, 10, 56],
      "P": [5, 56]
    }
    const max = Object.values(items).filter(v => Array.isArray(v)).reduce((c, v) => Math.max(c, ...v), Number.MIN_SAFE_INTEGER);
    console.log(max);

    filter 通过将逻辑合并到 reduce :

    var items = {
      "title": "Find Max",
      "A": [0, 78],
      "Z": [1],
      "R": [2, 10],
      "N": [2, 10, 56],
      "P": [5, 56]
    }
    const max = Object.values(items).reduce((c, v) => Array.isArray(v) ? Math.max(c, ...v) : c, Number.MIN_SAFE_INTEGER);
    console.log(max);

    如果不能使用ES6箭头功能,则可以:

    var items = {
      "title": "Find Max",
      "A": [0, 78],
      "Z": [1],
      "R": [2, 10],
      "N": [2, 10, 56],
      "P": [5, 56]
    }
    const max = Object.values(items).filter(function(v) {
      return Array.isArray(v);
    }).reduce(function(c, v) {
      return Math.max(c, ...v);
    }, Number.MIN_SAFE_INTEGER);
    console.log(max);

    数组.reduce 再次从数组中获取最大值:

    var items = {
      "title": "Find Max",
      "A": [0, 78],
      "Z": [1],
      "R": [2, 10],
      "N": [2, 10, 56],
      "P": [5, 56]
    }
    const max = Object.values(items).filter(function(v) {
      return Array.isArray(v);
    }).reduce(function(c, v) {
      return v.reduce(function(a, b) {
        return Math.max(a, b);
      }, c);
    }, Number.MIN_SAFE_INTEGER);
    console.log(max);
        2
  •  2
  •   Mulan    4 年前

    const items = {
      "title": "Find Max",
      "A": [0, 78],
      "Z": [1],
      "R": [2, 10],
      "N": [2, 10, 56],
      "P": [5, 56]
    }
    
    const nums =
      Object.values(items).flatMap(function (x) {
        if (Array.isArray(x))
          return x
        else
          return []
      })
      
    const result =
      Math.max(-Infinity, ...nums)
    
    console.log(result)
    // 78

    如果 items 不包含任何数字,结果将是 -Infinity


    如果允许的话,这里还有一个有趣的使用生成器的方法。我认为发电机在这种情况下特别有用,因为 input 是一个复杂的物体。 项目 是嵌套的,我们需要比较的一些值是非数值的。很高兴我们有一个 values 全部的 嵌套值-

    const values = function* (t)
    { if (Array.isArray(t))
        for (const v of t)
          yield* values(v)
      else if (Object(t) === t)
        for (const v of Object.values(t))
          yield* values(v)
      else
        yield t
    }
    
    const items = {
      "title": "Find Max",
      "A": [0, 78],
      "Z": [1],
      "R": [2, 10],
      "N": [2, 10, 56],
      "P": [5, 56]
    }
    
    let r = -Infinity
    for (const v of values(items))
      if (Number(v) === v)
        r = Math.max(r, v)
    console.log(r)
    // 78

    生成器返回迭代器。迭代器给我们一个值,在我们请求它之前不会计算下一个值。因此,发电机被称为“懒惰”。注意我们可以使用 for..of 遍历生成器,就像我们对数组所做的那样。

    但如果你使用这种技术,不要停在这里。即使生成器不返回数组,我们也可以编写代码,使我们能够以类似的方式将两者概念化。

    filter isNumber -

    const isNumber = function(x)
    { return Number(x) === x
    }
    
    const filter = function* (test, t)
    { for (const v of t)
        if (test(v))
          yield v
    }
    
    for (const v of filter(isNumber, values(items)))
      console.log(v)
    
    0
    78
    1
    2
    10
    2
    10
    56
    5
    56
    

    reduce -

    const reduce = function(f, init, t)
    { let r = init
      for (const v of t)
        r = f(r, v)
      return r
    }
    
    const result =
      reduce
        ( Math.max
        , -Infinity
        , filter(isNumber, values(items))
        )
    
    console.log(result)
    // 78
    

    const values = function* (t)
    { if (Array.isArray(t))
        for (const v of t)
          yield* values(v)
      else if (Object(t) === t)
        for (const v of Object.values(t))
          yield* values(v)
      else
        yield t
    }
    
    const filter = function* (test, t)
    { for (const v of t)
        if (test(v))
          yield v
    }
     
    const reduce = function(f, init, t)
    { let r = init
      for (const v of t)
        r = f(r, v)
      return r
    }
    
    const isNumber = function(x)
    { return Number(x) === x
    }
    
    const items = {
      "title": "Find Max",
      "A": [0, 78],
      "Z": [1],
      "R": [2, 10],
      "N": [2, 10, 56],
      "P": [5, 56]
    }
      
    const result =
      reduce
        ( Math.max
        , -Infinity
        , filter(isNumber, values(items))
        )
    
    console.log(result)
    // 78
        3
  •  1
  •   Soham    4 年前

    对新手来说不那么复杂的代码:

    var items = {
      "title": "Find Max",
      "A": [0, 78],
      "Z": [1],
      "R": [2, 10],
      "N": [2, 10, 56],
      "P": [5, 56]
    }
    
    let array = [];
    
    for (const property in items) {
      if (Array.isArray(items[property])) {
        let newArray = items[property];
        array = [...array, ...newArray]
      }
    }
    
    console.log(Math.max(...array)) // 78