【问题标题】:Array of JSON objects nested in array of JSON objects嵌套在 JSON 对象数组中的 JSON 对象数组
【发布时间】:2019-08-11 18:26:17
【问题描述】:

我有一个 JSON 格式的对象数组

var employees = 
[
  {
    "employee1": "employee1",
    "Details": [
      {
        "title": "Software Engineer",
        "EmployeeId": 451
      }
    ]
  },
  {
    "employee2": "employee2",
    "Details": []
  },
  {
    "employee3": "employee3",
    "Details": [
      {
        "title": "Test analyst",
        "EmployeeId": 453
      }
    ]
  },
  {
    "employee4": "employee4",
    "Details": [
      {
        "title": "Software engineer",
        "EmployeeId": 487
      },
      {
        "title": "Architect",
        "EmployeeId": 500
      }
    ]
  }
]

获取 EmployeeId 的最佳方式是什么?

预期输出:

[451,453,487,500]

我用的时候:

console.log(Object.assign({}, ...employees).Details.map(t=>t.EmployeeId))

返回结果为:

[487,500]

有没有办法在结果中连接其他员工 ID?

【问题讨论】:

  • 首先,不要再把它想象成 JSON ......它不是......它是一个 javascript 对象,json 是一种数据交换字符串格式 - 你没有处理那个 - 你明白吗为什么你的尝试没有成功?
  • employees.map(m => m.Details.map(m => m.EmployeeId)).flat()
  • @keith - 或employees.flatMap(m => m.Details.map(m => m.EmployeeId)) :p
  • @JaromandaX 是的,flatMap 会更好,我将它保持在 2 个地图上,希望能将 OP 指向他失败的方向。
  • @Keith 有没有办法在不使用平面图或平面的情况下找到值?我在节点版本

标签: javascript arrays node.js json object


【解决方案1】:

首先 - 它不是 JSON,只是一个数组。其次,像这样使用flatMapmap

var employees = [{
    "employee1": "employee1",
    "Details": [{
      "title": "Software Engineer",
      "EmployeeId": 451
    }]
  },
  {
    "employee2": "employee2",
    "Details": []
  },
  {
    "employee3": "employee3",
    "Details": [{
      "title": "Test analyst",
      "EmployeeId": 453
    }]
  },
  {
    "employee4": "employee4",
    "Details": [{
        "title": "Software engineer",
        "EmployeeId": 487
      },
      {
        "title": "Architect",
        "EmployeeId": 500
      }
    ]
  }
];

var ids = employees.flatMap(({ Details }) => Details.map(({ EmployeeId }) => EmployeeId));

console.log(ids);

没有 flatMap 的 Polyfill - 由 MDN's alternative 提供:

var employees = [{
    "employee1": "employee1",
    "Details": [{
      "title": "Software Engineer",
      "EmployeeId": 451
    }]
  },
  {
    "employee2": "employee2",
    "Details": []
  },
  {
    "employee3": "employee3",
    "Details": [{
      "title": "Test analyst",
      "EmployeeId": 453
    }]
  },
  {
    "employee4": "employee4",
    "Details": [{
        "title": "Software engineer",
        "EmployeeId": 487
      },
      {
        "title": "Architect",
        "EmployeeId": 500
      }
    ]
  }
];

var ids = employees.reduce((acc, { Details }) => acc.concat(Details.map(({ EmployeeId }) => EmployeeId)), []);

console.log(ids);

【讨论】:

  • 不幸的是,Array.prototype.flatMap() 的浏览器支持不多~developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • @Phil 我从不担心这个,transpile & polyfill。
  • 这很酷。只是想在开始之前添加一个注释“它说'flatMap不是一个函数'”
  • @Phil 我会给它添加一个 polyfill,别担心。
  • Array.prototype.flat() 在节点 中也不可用
【解决方案2】:

而不是使用具有可疑支持的flatMap(尽管我认为这是一个很好的答案,请注意)这是一个依赖于reducespread operator 的答案:

employees
  .reduce((a, v) => 
   ( v.Details && a.push(...v.Details.map(o=>o.EmployeeId)), a)
  , []);

没有spread,使用flat

employees
  .reduce((a, v) => 
   ( v.Details && a.push(v.Details.map(o=>o.EmployeeId)), a.flat(1))
  , []);

没有spreadflat,使用[].concat.apply([], arr)

employees
  .reduce((a, v) => 
   ( v.Details && a.push(v.Details.map(o=>o.EmployeeId)), [].concat.apply([], a))
  , []);

这些工作的示例:

var employees=[{employee1:"employee1",Details:[{title:"Software Engineer",EmployeeId:451}]},{employee2:"employee2",Details:[]},{employee3:"employee3",Details:[{title:"Test analyst",EmployeeId:453}]},{employee4:"employee4",Details:[{title:"Software engineer",EmployeeId:487},{title:"Architect",EmployeeId:500}]}];

let _

// setup our methods and name them

( 
array_concat = employees.reduce((a, v) => ( v.Details && a.push(v.Details.map(o=>o.EmployeeId)), [].concat.apply([], a)), [])
)
.name = "Using Array#concat",

(
spread = employees.reduce((a, v) => ( v.Details && a.push(...v.Details.map(o=>o.EmployeeId)), a), [])
)
.name = "Using Spread Operator",

(
flat = employees.reduce((a, v) => ( v.Details && a.push(v.Details.map(o=>o.EmployeeId)), a.flat(1)), [])
)
.name = "Using Flat",



// test if it works!

isCorrect = (arr, json = JSON.stringify(arr), {name} = arr) => 
console.info( json === "[451,453,487,500]" ? `${name} Passed!` : `${name} Failed`);

isCorrect(array_concat);
isCorrect(spread);
isCorrect(flat);

【讨论】:

    【解决方案3】:

    您可以尝试嵌套的reduce 方法。这工作很快,不使用任何 ES5 或更高版本。

    var employees = [{
        "employee1": "employee1",
        "Details": [{
          "title": "Software Engineer",
          "EmployeeId": 451
        }]
      },
      {
        "employee2": "employee2",
        "Details": []
      },
      {
        "employee3": "employee3",
        "Details": [{
          "title": "Test analyst",
          "EmployeeId": 453
        }]
      },
      {
        "employee4": "employee4",
        "Details": [{
            "title": "Software engineer",
            "EmployeeId": 487
          },
          {
            "title": "Architect",
            "EmployeeId": 500
          }
        ]
      }
    ];
    
    var ids = employees.reduce(function(a, b) {
        return b.Details.reduce(function(c, d) {
            c.push(d.EmployeeId);
            return c;
        }, a);
    }, []);
    
    console.log(ids);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 2011-12-02
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      相关资源
      最近更新 更多