2016-09-21 9 views
-1

У меня есть массив объектовGroup массив объектов в зависимости от значений

[ 
    { values: [2, 7, 1] }, 
    { values: [1, 2, 7] }, 
    { values: [7, 1, 2] }, 
    { values: [3, 4, 5] }, 
    { values: [2, 1, 8] }, 
    { values: [2, 1, 8] }, 
] 

Я хочу, чтобы сгруппировать эти объекты вместе с другим объектом с теми же значениями. Таким образом, этот массив объектов должен быть сгруппирован в 3 группы, поскольку первые 3 объекта имеют одинаковые значения, следующий объект один, а последние 2 объекта имеют одинаковые значения.

Как видно из примера, значения могут иметь разные порядки, но их все равно следует считать одинаковыми.

Я подумываю о том, чтобы каждый элемент пересекал оставшиеся элементы и видел, похожи ли они, но это приведет к O(n^2).

Я думаю, я должен удалить элементы из массива, который уже сгруппирован.

Так как я мог, эффективно, группа как

[[first, second, third],[fourth],[fifth,sixth]] 

ответ

2

Что-то вроде этого?

var data = [ 
 
    { values: [2, 7, 1] }, 
 
    { values: [1, 2, 7] }, 
 
    { values: [7, 1, 2] }, 
 
    { values: [3, 4, 5] }, 
 
    { values: [2, 1, 8] }, 
 
    { values: [2, 1, 8] }, 
 
]; 
 

 
var hash = {}; 
 
for(var obj of data) { 
 
    var key = obj.values.sort().join("-"); 
 
    if (!hash[key]) hash[key] = []; 
 
    hash[key].push(obj); 
 
} 
 
var result = []; 
 
for(var k in hash) result.push(hash[k]) 
 
console.log(result)

Или вариант JS6:

var data = [ 
 
    { values: [2, 7, 1] }, 
 
    { values: [1, 2, 7] }, 
 
    { values: [7, 1, 2] }, 
 
    { values: [3, 4, 5] }, 
 
    { values: [2, 1, 8] }, 
 
    { values: [2, 1, 8] }, 
 
]; 
 

 
var hash = data.reduce((hash, obj) => { 
 
    const key = obj.values.sort().join("-"); 
 
    if (!hash[key]) hash[key] = []; 
 
    hash[key].push(obj); 
 
    return hash; 
 
}, []) 
 

 
var result = Object.keys(hash).map(k => hash[k]) 
 
console.log(result)

+0

Да, это здорово. На самом деле меня не волнуют ключи. Можно ли предоставить им другие ключи (например, 1, 2, 3) и удалить их с пустыми массивами в свойстве 'values'? Я знаю, что могу использовать '.filter (function (obj) {return obj.values.length> 0;}) ...', но достаточно ли достаточно многократно вызывать 'obj.values'? – Jamgreen

+0

@Jamgreen checkout update – ruX

+0

@Jamgreen о '' '.filter()' '' я думаю, это не вопрос, связанный, но я не понимаю, почему он не эффективен. Конечно, это зависит от характера и объема данных – ruX

1

Вы можете сделать это с помощью forEach() петли и sort()

var arr = [ 
 
    { values: [2, 7, 1] }, 
 
    { values: [1, 2, 7] }, 
 
    { values: [7, 1, 2] }, 
 
    { values: [3, 4, 5] }, 
 
    { values: [2, 1, 8] }, 
 
    { values: [2, 1, 8] }, 
 
]; 
 

 
var result = []; 
 
arr.forEach(function(e) { 
 
    var s = [].concat(e.values).sort().join('|'); 
 
    if (!this[s]) { 
 
    this[s] = [e.values]; 
 
    result.push(this[s]); 
 
    } else { 
 
    this[s].push(e.values) 
 
    } 
 
}) 
 

 
console.log(result)

Смежные вопросы