简体   繁体   中英

Arrays two dimensional convert to small array

Have an array arr =

[ [1,2] , [5,1], [23,24], [3,4], [22,23], [2,3]]
output needed = [[5,1,2,3,4],[22,23,24]]

tried using concat, reduce methods of array in javascript but could not achieve the desired result - any ideas?

I'm going to start by saying the code example and description is not very clear, but I'll take a shot...

It seems you have 3 requirements:

  • Flatten the original array.
  • Filter out duplicates.
  • Group values (somehow?) within the flattened array.

The first 2 tasks on the list can be accomplished using reduce, concat, filter and indexOf methods.

var multiArray = [ [1,2] , [5,1], [23,24], [3,4], [22,23], [2,3] ];

var flattened = multiArray.reduce(function (prev, curr) {
    return prev.concat(curr);
}, []);

var unique = flattened.filter(function (element, index, array) {
    return array.indexOf(element) === index;
});

However, I wont be able to give you an example for that last task until you make it clear how you're hoping to have these values grouped within the flattened array.

I'll update my original answer once clarified.

Basically this problem can be solved with more loops and only one array (A) or with an object as reference and only one loop (B).

A

An in situ proposal with no object, but with more loops. It checks every array with the path information with each other. If a match is found, the two arrays are

 var data = [[1, 2], [5, 1], [23, 24], [3, 4], [22, 23], [2, 3], [4, 5]], result = function (data) { function first(a) { return a[0]; } function last(a) { return a[a.length - 1]; } var i = 0, j, t; outer: while (i < data.length - 1) { j = i + 1; while (j < data.length) { t = data.splice(j, 1)[0]; if (first(data[i]) === last(t)) { t.pop(); data[i] = t.concat(data[i]); i = 0; continue outer; } if (last(data[i]) === first(t)) { t.shift(); data[i] = data[i].concat(t); i = 0; continue outer; } data.push(t); j++; } i++ } return data; }(data); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>'); 

B

This is a single loop proposal which takes all parts and appends them if possible. Later all start arrays are returned as result.

 var data = [[1, 2], [5, 1], [23, 24], [3, 4], [22, 23], [2, 3], [4, 5]], result = function (data) { var o = { start: {}, end: {} }; data.forEach(function (a) { var temp; if (o.end[a[0]]) { if (o.start[a[1]] && a[0] !== o.start[a[1]][o.start[a[1]].length - 1] && a[1] !== o.end[a[0]][0]) { temp = o.end[a[0]].concat(o.start[a[1]]); o.start[temp[0]] = temp; o.end[temp[temp.length - 1]] = temp; delete o.start[a[1]]; } else { o.end[a[1]] = o.end[a[0]]; o.end[a[1]].push(a[1]); } delete o.end[a[0]]; return; } if (o.start[a[1]]) { o.start[a[0]] = o.start[a[1]]; o.start[a[0]].unshift(a[0]); delete o.start[a[1]]; return; } temp = a.slice(); o.start[a[0]] = temp; o.end[a[1]] = temp; }); return Object.keys(o.start).map(function (k) { return o.start[k]; }); }(data); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>'); 

This is another solution yet i believe i can make it with less code and more functional. I don't enjoy using forEach() or flags like reduced much. This one recursively encodes the array items until there is nothing left to encode. Later I will give it another try to make it look more sleek.

 var rawarr = [[1,2], [5,1], [23,24], [3,4], [22,23], [2,3]], encodarr = (arr) => { var reduced = false; arr.forEach((c,i,a) => { var sa = a.slice(i+1), j = sa.findIndex(f => c[0] == f[f.length-1] || c[c.length-1] == f[0]); arr[i] = !!~j ? c[0] == sa[j][sa[j].length-1] ? (reduced = true, a.splice(i+j+1,1)[0].concat(c.slice(1))) : (reduced = true, c.slice(0,-1).concat(a.splice(i+j+1,1)[0])) : c; return arr; }); return reduced ? encodarr(arr) : arr; }; document.write("<pre>" + JSON.stringify(encodarr(rawarr)) + "</pre>"); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM