Search code examples
javascriptarraysjavascript-objects

Creating nested arrays of set structure


I have an array of objects with named keys as follows:

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

Note that there might be objects without these keys. They should be skipped.
Having all this I want to create a new Array of arrays with 2 objects inside with the following rigid structure:

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

How one could achieve it in the most efficient and fast way?


Solution

  • Ok, I want to have my try as well! Why did nobody think about reduce? It's faster than for-loop! And more elegant. IMO at least.

    So I've done few tests, and here are results:

    enter image description here

    And heres the code:

    1) Array.prototype.reduce() with 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() with 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() with spread operator

    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) And @Emueeus go. For-loop with Array.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']}])
      }
    }
    

    Here's the test: http://jsfiddle.net/4bca0g2u/