Creating nested arrays of set structure

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?





What have you tried so far?
– Helping hand
Aug 25 at 14:14





Thank you for your question! I know how to create a simple object name: 'town1', value: 'distance' by reducing or mapping forEach(a => ). But I can't figure out how to iterate 2 objects inside array inside another array...
– Igniter
Aug 25 at 14:22





Isn't the output supposed to be [ name: 'London', value: 123456 , name: 'Paris' ]?
– Aadit M Shah
Aug 25 at 14:27


[ name: 'London', value: 123456 , name: 'Paris' ]





Yep! And these values would vary depending on objects inside Array1.
– Igniter
Aug 25 at 14:29




4 Answers
4



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()


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() with Array.prototype.concat()


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() with spread operator


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) And @Emueeus go. For-loop with Array.prototype.push()


For-loop


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/





Thank you for your answer! Now that's confusing! I'm constantly getting various results using jsperf.com on your 4 tests. Looks like these tests are conducted on my machine, which is not very trustworthy, so there should be kind of remote-like services. If you know any online script measuring tools like Pingdom or Google Speed for websites, please share!
– Igniter
Aug 25 at 18:23





Here it is: jsperf.com/reduces-vs-for-loop. What do you use for testing performance?
– Igniter
Aug 25 at 18:25





@Igniter I wrote a quick performance test. Iterated each of those solutions 100k times, measured their performance with performance.now() and divided the result by the iteration count. I've fired it on my local machine, you might be right, testing it on multiple environments would give a more trustworthy result. Here's the test through jsfiddle.net/4bca0g2u
– Patryk Cieszkowski
Aug 25 at 19:52


performance.now()





I agree because you did one iteration, I'm not agree that it is more elegant. :)
– Emeeus
Aug 25 at 20:38





@Emeeus oh, you have every right to do so :) Although native functions seem to be more readable than for-loop. At least to me
– Patryk Cieszkowski
Aug 25 at 21:09



MinusFour's solution is almost correct. You'd also want to filter the elements which actually have the keys required:


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



Is that what you're looking for?



Looks like a single map would work for you.


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 ])



Edit: Didn't see that you didn't want to map objects without those keys. The filter takes care of that.





it would, but would throw undefined if any of those keys would be missing. OP wants those objects to be skipped
– Patryk Cieszkowski
Aug 25 at 14:30





@PatrykCieszkowski didn't see it, fixed.
– MinusFour
Aug 25 at 14:34



Just one iteration ( O(n) ) using for. It's faster than filter and map (2 iterations) see this https://jsperf.com/mapfiltervsfor/1


for




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)





First, interesting! That was unexpected I should say. Thank you for separate concerns about performance and the link to that site I didn't know about! I prefer this approach!
– Igniter
Aug 25 at 15:49





@Igniter Thanks, as a general rule (maybe not always), native methods like .map .sort, .filter.. etc. are faster than plain for but sometimes those methods doesn't resolve the whole issue, and we have to use them more than once, in those cases is preferably in my opinion, to use for if we can resolve the issue with less iterations .
– Emeeus
Aug 25 at 16:01


.map


.sort


.filter


for


for






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ

How do I collapse sections of code in Visual Studio Code for Windows?