创建集合结构的嵌套数组

时间:2018-08-25 14:10:51

标签: javascript arrays javascript-objects

我有一个带有命名键的对象数组,如下所示:

Array1 [
  {
    'town1': 'London', // string
    'town2': 'Paris', // string
    'distance': 123456, // number
  },
  {
    'town1': 'Seoul', // string
    'town2': 'Tokio', // string
    'distance': 654321, // number
  },
  {},{},... // Objects with same properties
]

请注意,某些对象可能没有这些键。应该跳过它们。
有了这些,我想创建一个新的内部有2个对象的数组,其结构如下:

Array2 [
  [{ name: 'town1', value: 'distance'}, { name: 'town2'}],
  [{ name: 'town1', value: 'distance'}, { name: 'town2'}],
  [{...}, {...}],   // All other objects with existing town1-town2-distance
]

如何以最有效,最快捷的方式实现它?

4 个答案:

答案 0 :(得分:2)

看起来像一个map会为您服务。

let mustHave = ['town1', 'town2', 'distance'];
Array1.filter(obj => mustHave.every(key => obj.hasOwnProperty(key))
      .map(obj => [{ name : obj.town1, value: obj.distance}, { name : obj.town2 }])

编辑:没有看到您不想在没有这些键的情况下映射对象。过滤器会解决这个问题。

答案 1 :(得分:2)

MinusFour的解决方案几乎是正确的。您还希望过滤实际上具有所需键的元素:

Array2.filter(obj => obj.hasOwnProperty("town1") &&
                     obj.hasOwnProperty("town2") &&
                     obj.hasOwnProperty("distance"))
      .map(obj => [{ name: obj.town1, value: obj.distance }, { name: obj.town2 }]);

这是您要找的吗?

答案 2 :(得分:2)

使用for进行一次迭代(O(n))。它比筛选和映射(2次迭代)要快,请参阅此https://jsperf.com/mapfiltervsfor/1

var array1 = [
    {
      'town1': 'London', // string
      'town2': 'Paris', // string
      'distance': 123456, // number
    },
    {
      'town1': 'Seoul', // string
      'town2': 'Tokio', // string
      'distance': 654321, // number
    }
  ];

  var array2 = [];

  for(let i = 0; i<array1.length; i++){

     if(array1[i].hasOwnProperty('town1') &&  array1[i].hasOwnProperty('town2') && array1[i].hasOwnProperty('distance')){
        array2.push([{name:array1[i]['town1'], value: array1[i]['distance']}, { name: array1[i]['town2']}])
     }

  }
  console.log(array2)

答案 3 :(得分:1)

好的,我也想尝试一下!为什么没人考虑减少?它比for循环快!而且更优雅。至少是IMO。

所以我做了一些测试,结果如下:

enter image description here

下面是代码:

1)Array.prototype.reduce()Array.prototype.push()

const array2 = array1.reduce((arr, obj) => {
  if (obj.hasOwnProperty('town1') && obj.hasOwnProperty('town2') && obj.hasOwnProperty('value')) {
    arr.push([ { name: obj.town1, value: obj.distance }, { name: obj.town2 } ])
  }

  return arr
}, [])

2)Array.prototype.reduce()Array.prototype.concat()

const array2 = array1.reduce((arr, obj) => (
  (obj.hasOwnProperty('town1') && obj.hasOwnProperty('town2') && obj.hasOwnProperty('value'))
    ? Array.prototype.concat(arr, [[ { name: obj.town1, value: obj.distance }, { name: obj.town2 } ]])
    : arr
  ), [])

3)Array.prototype.reduce()与传播算子

array2 = array1.reduce((arr, obj) => (
  (obj.hasOwnProperty('town1') && obj.hasOwnProperty('town2') && obj.hasOwnProperty('value'))
    ?  [...arr, [ { name: obj.town1, value: obj.distance }, { name: obj.town2 } ]]
    : arr
  ), [])

4)@Emueeus去。 For-loopArray.prototype.push()

for (let i = 0; i<array1.length; i++) {
  if (array1[i].hasOwnProperty('town1') && array1[i].hasOwnProperty('town2') && array1[i].hasOwnProperty('distance')) {
    array2.push([{name:array1[i]['town1'], value: array1[i]['distance']}, { name: array1[i]['town2']}])
  }
}

这是测试: http://jsfiddle.net/4bca0g2u/