admin管理员组

文章数量:1434960

I have an array that contains different clothes and the type of the cloth. For example, I may have a specific shirt that belongs to the shirts category. What I want to do is get all the types from an array and ignore any duplicate entries. So if I have 3 shirts and 2 trousers, I will only get 1 shirt and 1 trouser.

array = [
    {
        name: "test 1",
        type: "shirt"
    },
  {
        name: "test 2",
        type: "shirt"
    },
  {
        name: "test 3",
        type: "trousers"
    },
  {
        name: "test 4",
        type: "trousers"
    }
];

var categories = {};
for(var i = 0, len = array.length; i < len; i++) {
    if(categories.indexOf(array[i].type) > -1) {
    console.log('Duplicate type');
  }
  else {
    console.log('New type');
    categories.push(array[i].type);
  }
}

But I end up getting TypeError: categories.indexOf is not a function.

I have an array that contains different clothes and the type of the cloth. For example, I may have a specific shirt that belongs to the shirts category. What I want to do is get all the types from an array and ignore any duplicate entries. So if I have 3 shirts and 2 trousers, I will only get 1 shirt and 1 trouser.

array = [
    {
        name: "test 1",
        type: "shirt"
    },
  {
        name: "test 2",
        type: "shirt"
    },
  {
        name: "test 3",
        type: "trousers"
    },
  {
        name: "test 4",
        type: "trousers"
    }
];

var categories = {};
for(var i = 0, len = array.length; i < len; i++) {
    if(categories.indexOf(array[i].type) > -1) {
    console.log('Duplicate type');
  }
  else {
    console.log('New type');
    categories.push(array[i].type);
  }
}

But I end up getting TypeError: categories.indexOf is not a function.

Share Improve this question asked Jun 16, 2016 at 10:09 WokkiWokki 1571 gold badge2 silver badges18 bronze badges 3
  • Agreed with @A.Rossi, you need to apply if condition in your array – Pravesh Khatri Commented Jun 16, 2016 at 10:13
  • categories is defined as an object (not ordered) so there is no indexOf. – Dellirium Commented Jun 16, 2016 at 10:14
  • 1 @ibab Don't listen to them. Read the answers below. – VisioN Commented Jun 16, 2016 at 10:15
Add a ment  | 

5 Answers 5

Reset to default 4

Pretty short solution using ES6 Set object:

The Set object lets you store unique values of any type, whether primitive values or object references.

var categories = new Set();
array.forEach((o) => categories.add(o.type));
categories = [...categories];  // Set to Array transformation

console.log(categories);  // ["shirt", "trousers"]

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

You need an array for categories, not an object.

var categories = [];

array = [
    {
        name: "test 1",
        type: "shirt"
    },
  {
        name: "test 2",
        type: "shirt"
    },
  {
        name: "test 3",
        type: "trousers"
    },
  {
        name: "test 4",
        type: "trousers"
    }
];

var categories = [];
for(var i = 0, len = array.length; i < len; i++) {
    if(categories.indexOf(array[i].type) > -1) {
    console.log('Duplicate type');
  }
  else {
    console.log('New type');
    categories.push(array[i].type);
  }
}
console.log(categories);

This happens because you define categories as object literal ({}), rather than an array ([]):

// --------------vv
var categories = {};

Your issue is that you are trying to invoke .push method on an object but the method is available only on Array. You need to make categories an array in order to push to it.

As an alternative, you can use pure function without any mutations using Array.prototype.reduce() to reduce the array of duplicate objects to unique ones:

var array = [
    {
        name: "test 1",
        type: "shirt"
    },
  {
        name: "test 2",
        type: "shirt"
    },
  {
        name: "test 3",
        type: "trousers"
    },
  {
        name: "test 4",
        type: "trousers"
    }
];


function unique(input) {
  return input.reduce(function (acc, current) {
    if (acc.indexOf(current.type) > -1) {
      return acc 
    } else {
      return acc.concat([current.type]);
    }
  }, [])
  
}

var categories = unique(array);
console.log(categories);

If you want to see the result of every row then I think first implementation could be the answer but if you want just the categories then using map make it simple.

array = [
	{ name: "test 1", type: "shirt" }, 
	{ name: "test 2", type: "shirt" }, 
	{ name: "test 3", type: "trousers" }, 
	{ name: "test 4", type: "trousers" }
];

// --------------------------------------
var categories = [];
array.forEach(v => {
	if (this[v.type])
		return console.log('Duplicate type');
	console.log('New type');
	this[v.type] = true;
	categories.push(v.type);
}, {});

console.log(categories);
// --------------------------------------
var map = new Map;
array.forEach(v => map.set(v.type, v.type));
categories = [...map.keys()];

console.log(categories);

本文标签: JavaScript Get values from array but ignore duplicatesStack Overflow