【问题标题】:Filter array of objects based a nested array of objects基于嵌套的对象数组过滤对象数组
【发布时间】:2018-03-18 17:04:05
【问题描述】:

我有一个数组:

myData: [{
   name: "",
   lastName: "",
   historicalData: [{
    data1: '',
    data2: 0,
   },
    {
    data1: '',
    data2: 30,
   }
  ]
},
{
   name: "",
   lastName: "",
   historicalData: [{
    data1: '',
    data2: 6,
   },
    {
    data1: '',
    data2: 1,
   }
  ]
 }
]

我想遍历这个数组,过滤它以获得 data2 > 2 的所有数据。然后按 data1 对结果进行排序。

由于它是对象数组中的嵌套对象数组,我不确定如何在 es6 中迭代和过滤。

有什么建议吗?

myData.filter(oneData => historicalData.data1 > 2)

但最初我也必须通过历史数据进行映射。 预期结果:

myData: [{
  name: "",
  lastName: "",
  historicalData: [{
    data1: '',
    data2: 30,
  }]
},{
  name: "",
  lastName: "",
    historicalData: [{
    data1: '',
    data2: 6,
  }]
}]

一旦我得到这个结果,我就可以进行相应的排序。 谢谢

【问题讨论】:

  • 你想取内部数组的data2 中的哪一个?请同时添加想要的结果。
  • 所以我需要用户 1 的示例,循环遍历内部的历史数据,只过滤掉那些数据 2 > 2 的数据。然后对用户 2 进行同样的操作。然后对结果进行排序。将编辑它!
  • 应该对哪个数组进行排序?

标签: javascript ecmascript-6


【解决方案1】:

您可以构建新对象并过滤historicalData

此解决方案不会改变原始数据。

var data = [{ name: "", lastName: "", historicalData: [{ data1: '', data2: 0, }, { data1: '', data2: 30, }] }, { name: "", lastName: "", historicalData: [{ data1: '', data2: 6, }, { data1: '', data2: 1, }] }],
    filtered = data.map(o =>
        Object.assign({}, o, { historicalData: o.historicalData.filter(({ data2 }) => data2 > 2) }));

console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 非常感谢!谢谢
  • 在 .filter(({data2}) => data2 >2) 之后我可以添加一个 .sort( 基于 data1 的降序) 吗?
  • 你可以在这个地方添加排序。
【解决方案2】:

var myData = [{
    name: "",
    lastName: "",
    historicalData: [{
        data1: '',
        data2: 0,

    }, {
        data1: '',
        data2: 30,

    }]
}, {
    name: "",
    lastName: "",
    historicalData: [{
        data1: '',
        data2: 6,

    }, {
        data1: '',
        data2: 1,

    }]
}];

var res = myData.map( (a) => {
  a["historicalData"] = a["historicalData"].filter( (aa) => aa["data2"] > 2 );
  return a;
});

// since you were unclear about the historicalData 
// array length and how you choose set to 0
res = res.sort( (a,aa) => a["historicalData"][0].data1 - aa["historicalData"][0].data1 );
console.log(res);

【讨论】:

    【解决方案3】:

    过滤

     myData.map(x => x.historicalData = x.historicalData.filter(x => x.data2 >2))
    

    如果你也想排序

    myData.map(x => x.historicalData = x.historicalData.filter(x => x.data2 >2).sort((y,z)=> y.data1.localeCompare(z.data1) ))
    

    如果你想在没有变异的情况下进行排序和过滤

    myData.map( m => { 
      return { 
        ...m , 
        ...{ historicalData: m.historicalData.filter(data  => data.data2 > 2) .sort((y,z)=> y.data1.localeCompare(z.data1))} 
      } 
    });
    

    编辑:添加了 localeCompare,因为它是进行字符串排序的正确方法。

    【讨论】:

    • 该解决方案会改变原始数据。
    • @NinaScholz 我理解你的观点。但考虑到问题不变性的背景似乎并不值得关注。
    • @NinaScholz ES6 文档说 map 不会改变调用它的数组(尽管回调,如果被调用,可能会这样做)。它是如何变异的?如果我遗漏了什么,我很抱歉,我是初学者,想明白你的意思
    • @JeffM 对,map 不会发生变异,但赋值会发生变化:x.historicalData = x.historicalData.fillter(...)
    • 啊,我没注意到。谢谢!!
    猜你喜欢
    • 1970-01-01
    • 2016-11-17
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2020-03-11
    • 1970-01-01
    • 2020-03-08
    相关资源
    最近更新 更多