Получить уникальные объекты из массива на основе одного атрибута

Допустим, у нас есть следующее:

node[1].name = "apple";
node[1].color = "red";
node[2].name = "cherry";
node[2].color = "red";
node[3].name = "apple";
node[3].color = "green";
node[4].name = "orange";
node[4].color = "orange;

если я использую jQuery.unique(узел), я получу все исходные узлы, потому что все они имеют другое имя ИЛИ цвет. Я хочу получить только узлы с уникальным именем, которые должны вернуть

node[1] (apple)
node[2] (cherry)
node[4] (orange)

Он не должен возвращать 3, потому что это один и тот же фрукт, хотя у нас есть зеленые и красные яблоки.

3 ответа

Решение

Использование Array.filter и временный массив для хранения дубликатов:

function filterByName(arr) {
  var f = []
  return arr.filter(function(n) {
    return f.indexOf(n.name) == -1 && f.push(n.name)
  })
}

Демо: http://jsfiddle.net/mbest/D6aLV/6/

Этот подход (разветвленный от @David's) должен иметь лучшую производительность для больших входов (потому что object[] является O(1)).

function filter(arr, attribute) {
  var out = [],
      seen = {}

  return arr.filter(function(n) {
      return (seen[n[attribute]] == undefined) 
              && (seen[n[attribute]] = 1);
  })
}

console.log(filter(node, 'name'));

http://jsfiddle.net/LEBBB/1/

Как насчет этого?

var fruitNames = [];
$.each($.unique(fruits), function(i, fruit) {
    if (fruitNames.indexOf(fruit.name) == -1) {
        fruitNames.push(fruit.name);
        $('#output').append('<div>' + fruit.name + '</div>');
    }
});

Вот рабочая скрипка.

Очевидно, что вместо output.append я мог бы просто добавить текущий фрукт в uniqueFruit[] или что-то еще.

Другие вопросы по тегам