-3

I have the following script that's supposed to uniqualize array:

function uniques(arr) {
var a = [];
for (var i=0, l=arr.length; i<l; i++)
    for (var j = 0; j < arr[i].length; j++) {
        if (a.indexOf(arr[i][j]) === -1 && arr[i][j] !== '')   {
            a.push(arr[i][j]);
        }
    }
return a;
}

However, when it receives only one element, it just breaks it into the letters (which is understandable).

Do you know how I make it check if it's receiving only one element and then returns it back?

Thanks!

Aerodynamika
  • 7,883
  • 16
  • 78
  • 137

3 Answers3

1

I'm not sure why you need the nested loop - you only need a single loop if you're processing a non-nested array:

function uniques(arr) {
  if (arr.length === 1) { return arr };
  var a = [];
  for (var i = 0, l = arr.length; i < l; i++) {
    if (a.indexOf(arr[i]) === -1) {
      a.push(arr[i]);
    }
  }
  return a;
}

DEMO

If you want to process nested arrays, use a recursive function. Here I've used underscore's flatten method as the basis:

function toType(x) {
  return ({}).toString.call(x).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
}

function flatten(input, output) {
  if (!output) { output = []; }
  for (var i = 0, l = input.length; i < l; i++) {
    var value = input[i];
    if (toType(value) !== 'array' && output.indexOf(value) === -1) {
      output.push(value);
    } else {
      flatten(value, output);
    }
  }
  return output.sort(function (a, b) { return a - b; });
};

var arr = [1, 2, 3, [[4]], [10], 5, 1, 3];
flatten(arr); // [ 1, 2, 3, 4, 5, 10 ]

DEMO

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

I think the solution is this:

function uniques(arr) {

if (arr.length > 1) {
var a = [];
for (var i=0, l=arr.length; i<l; i++)
    for (var j = 0; j < arr[i].length; j++) {
        if (a.indexOf(arr[i][j]) === -1 && arr[i][j] !== '')   {
            a.push(arr[i][j]);
        }
    }
return a;
}
else
{
return arr;
}
}
Rui Silva
  • 140
  • 11
-1

What you're trying to do is a linear search on the created matrix for each item in the original one.

The solution below will accomplish this, but at a great cost. If your original matrix is 50x50 with unique values in each cell, it will take you 50^3 (=125000) loops to exit the function.

The best technique to search, in programming science, takes O(log(N)) that means that if you'll use it on your problem it will take log(50^2) (=11) loops.

function uniques(arr) {
  var items = [];
  var a = arr.map(function(row, i) {
    return row.map(function(cell, j) {
      if (items.indexOf(cell) >= 0) {
        items.push(cell);
        return cell;
      }
    });
  });
}
Eyal
  • 758
  • 6
  • 23
  • strange, because when it receives something like ['private', ''] it takes the first string and separates it into letters. i think there should be an array / string check somewhere? – Aerodynamika Dec 10 '14 at 13:47
  • I don't understand your comment. – Eyal Dec 10 '14 at 13:49
  • If you do want to incorporate a better search function than you should read [Computer science in JavaScript: Binary search tree](http://www.nczonline.net/blog/2009/06/09/computer-science-in-javascript-binary-search-tree-part-1/) – Eyal Dec 10 '14 at 13:52
  • I've updated my answer to use more modern techniques. It still cost O(N^3) – Eyal Dec 10 '14 at 14:02