-1

I have a list of Vector() objects

pointList = [(1688, 25), (1349.75, 25), (1349.75, 395), (1688, 395), (900, 395), (900, 25), (450.25, 25), (450.25, 395), (8, 395), (8, 25)]

and I would like to orginize them in an array of array of objects which first index correspond to line and second index correspont to column

matrix = []; matrix[0] = [(8, 25), (450.25, 25), (900, 25), (1349.75, 25), (1688, 25)] matrix[1] = [(8, 395), (450.25, 395), (900, 395), (1349.75, 395), (1688, 395)] matrix[2] = [...]

and so on

The point list Vector() object come from here

var pointList = new Array(); for (var i = 0; i < getNumberOfCyclePoints(); ++i) { pointList.push(getCyclePoint(i)); }

getNumberOfCyclePoints() return me int with the total number of points getCyclePoint(int) return me a Vector() objects

3 Answers3

0

Maybe this works for you.

function sortAsc(a, b) { return a - b; }
function makeObject(o) { return function (a, i) { o[a] = i; }; }

var pointList = [[1688, 25], [1349.75, 25], [1349.75, 395], [1688, 395], [900, 395], [900, 25], [450.25, 25], [450.25, 395], [8, 395], [8, 25]],
    x = {},
    y = {},
    matrix = [];

pointList.reduce(function (r, a) { !~r.indexOf(a[0]) && r.push(a[0]); return r; }, []).sort(sortAsc).forEach(makeObject(x)),
pointList.reduce(function (r, a) { !~r.indexOf(a[1]) && r.push(a[1]); return r; }, []).sort(sortAsc).forEach(makeObject(y)),

pointList.forEach(function (a) {
    var i = x[a[0]], j = y[a[1]];
    matrix[j] = matrix[j] || [];
    matrix[j][i] = a;
});
document.write('<pre>' + JSON.stringify(matrix, 0, 4) + '</pre>');

Solution with a different approach and a kind of Vector:

function Vector(x, y) {
    this.x = x;
    this.y = y;
}

function transpose(l) {
    var array = [], obj = new Vector([], []);

    l.forEach(function (v) {
        var x = obj.x.indexOf(v.x),
            y = obj.y.indexOf(v.y);

        if (!~x && !~y) {
            array.push([v]);
            obj.x.push(v.x);
            obj.y.push(v.y);
            return;
        }
        if (!~x) {
            obj.x.every(function (a, i) {
                if (a < v.x) { return true; }
                array.forEach(function (b) { b.splice(i, 0, undefined); });
                obj.x.splice(i, 0, v.x);
                x = i;
            }) && (
                array.forEach(function (b) { b.push(undefined); }),
                x = obj.x.push(v.x) - 1
            );
        }
        if (!~y) {
            obj.y.every(function (a, i) {
                if (a < v.y) { return true; }
                array.splice(i, 0, Array.apply(null, { length: obj.x.length }));
                obj.y.splice(i, 0, v.y);
                y = i;
            }) && (
                array.push(Array.apply(null, { length: obj.x.length })),
                y = obj.y.push(v.y) - 1
            );
        }
        array[y][x] = v;
    });
    return array;
}

var pointList = [
        new Vector(1688, 25),
        new Vector(1349.75, 25),
        new Vector(1349.75, 395),
        new Vector(1688, 395),
        new Vector(900, 395),
        new Vector(900, 25),
        new Vector(450.25, 25),
        new Vector(450.25, 395),
        new Vector(8, 395),
        new Vector(8, 25)
    ],
    matrix = transpose(pointList);

document.write('<pre>' + JSON.stringify(matrix, 0, 4) + '</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • This works for the type of point list of the example that I show but in reality my point list is a list of Vector() objects. May be I explain wrong myself. Sorry. Could you help to work this algorithm in a list of Vector() objects? – Bruno Dias Vasconcelos Nov 18 '15 at 17:07
  • @BrunoDiasVasconcelos, yes, i can, but i need `Vector()`. – Nina Scholz Nov 19 '15 at 09:51
0

You can use reduce to capture the correct groups in an object, and then simply loop over the object to push those arrays into a new array:

var obj = pointList.reduce(function (p, c) {
  var key = c[1];
  p[key] = (p[key] || []);
  p[key].push(c);
  return p;
}, {});

var sorter = function (a, b) { return a[0] - b[0]; }

var result = [];
for (var p in obj) {
  result.push(obj[p].sort(sorter));
}

DEMO

Andy
  • 61,948
  • 13
  • 68
  • 95
0

Here is another possible solution...

var p = [
    {x: 1688, y: 25},
    {x: 1349.75, y: 25},
    {x: 1349.75, y: 395},
    {x: 1688, y: 395},
    {x: 900, y: 395}, 
    {x: 900, y: 25},
    {x: 450.25, y: 25},
    {x: 450.25, y: 395},
    {x: 8, y: 395},
    {x: 8, y: 25}
];
var m = [];
for (var k = 0; k < p.length; k++) {
    var inserted = false;
    for (var i = 0; !inserted && i < m.length; i++) {
        if (p[k].y < m[i][0].y) {
            m.splice(i, 0, [p[k]]);
            inserted = true;
        }
        else if (p[k].y == m[i][0].y) {
            for (var j = 0; j < !inserted && m[i].length; j++) {
                if (p[k].x < m[i][j].x) {
                    m[i].splice(j, 0, p[k]);
                    inserted = true;
                }
            }
            if (!inserted) {
                m[i].push(p[k]);
                inserted = true;
            }
        }
    }
    if (!inserted) {
        m.push([p[k]]);
        inserted = true;
    }
}
console.log(JSON.stringify(m));
Bobby Orndorff
  • 3,265
  • 1
  • 9
  • 7