2016-11-25 2 views
0

У меня есть массив объектов javascript с некоторым ключом и значением. Ниже приведен пример моего массива.удалить дубликаты из массива объектов

[ 
{ 
"timestamp": 1474328370007, 
"message": "hello" 
}, 
{ 
"timestamp": 1474328302520, 
"message": "how are you" 
}, 
{ 
"timestamp": 1474328370007, 
"message": "hello" 
}, 
{ 
"timestamp": 1474328370007, 
"message": "hello" 
} 
] 

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

ожидается выход

[ 
{ 
"timestamp": 1474328302520, 
"message": "how are you" 
}, 
{ 
"timestamp": 1474328370007, 
"message": "hello" 
} 
] 

пытается что-то вроде этого

var fs = require('fs'); 

fs.readFile("file.json", 'utf8', function (err,data) { 
if (err) console.log(err);; 
console.log(data); 
// var result = []; 
for (i=0; i<data.length;i++) { 
    if(data[i].timestamp != data[i+1].timestamp) 
    console.log('yes'); 
    } 
}); 

Я не могу понять data[i+1] часть после того, как заканчивается массив. Есть ли какой-либо простой способ, с помощью которого я могу выполнить вышеупомянутую дедупликацию?

спасибо заранее

+0

http://underscorejs.org/#uniq –

ответ

4

Вы можете использовать объект в качестве хэш-таблицы и проверку.

var array = [{ "timestamp": 1474328370007, "message": "hello" }, { "timestamp": 1474328302520, "message": "how are you" }, { "timestamp": 1474328370007, "message": "hello" }, { "timestamp": 1474328370007, "message": "hello" }], 
 
    result = array.filter(function (a) { 
 
     return !this[a.timestamp] && (this[a.timestamp] = true); 
 
    }, Object.create(null)); 
 

 
console.log(result);

Вы можете использовать переменные для хэша и один для отфильтрованного результата, как

var hash = Object.create(null), 
    result = []; 

for (i = 0; i < data.length; i++) { 
    if (!hash[data[i].timestamp]) { 
     hash[data[i].timestamp] = true; 
     result.push(data[i]); 
    } 
} 
+0

Это очень умный! – sabithpocker

+0

@ Нина благодарю вас за ответ. Только этот код работает. Но я обслуживаю массив из файла. как внести изменения для такого подхода? – csvb

+0

получение ошибки 'data.filter не является функцией'. что я пропустил здесь? – csvb

0

Вы можете использовать уменьшить и получить уникальные предметы

чека этот фрагмент

var arr = [{ 
 
    "timestamp": 1474328370007, 
 
    "message": "hello" 
 
}, { 
 
    "timestamp": 1474328302520, 
 
    "message": "how are you" 
 
}, { 
 
    "timestamp": 1474328370007, 
 
    "message": "hello" 
 
}, { 
 
    "timestamp": 1474328370007, 
 
    "message": "hello" 
 
}]; 
 

 
var elements = arr.reduce(function(previous, current) { 
 

 
    var object = previous.filter(object => object.timestamp === current.timestamp); 
 
    if (object.length == 0) { 
 
    previous.push(current); 
 
    } 
 
    return previous; 
 
}, []); 
 

 
console.log(elements);

Надеется, что это помогает

+0

Спасибо, Geeky. Это помогает. Можете ли вы объяснить, как работает этот код? Я не могу понять, что делает эта строка: как сокращение используется для получения уникальных значений? – csvb

+0

Что делает эта линия? 'var object = previous.filter (object => object.timestamp === current.timestamp);' и 'return previous;}, [])' – csvb

+0

Он фильтрует объекты, в которых уже существующие элементы и текущие элементы отметка времени равна – Geeky

0

Простого способу сделать это, чтобы использовать массив флагов. Есть определенно лучшие способы, но это довольно простой способ сделать это, что должно сработать для вас.

data = [ 
 
     { 
 
      "timestamp": 1474328370007, 
 
      "message": "hello" 
 
     }, 
 
     { 
 
      "timestamp": 1474328302520, 
 
      "message": "how are you" 
 
     }, 
 
     { 
 
      "timestamp": 1474328370007, 
 
      "message": "hello" 
 
     }, 
 
     { 
 
      "timestamp": 1474328370007, 
 
      "message": "hello" 
 
     } 
 
    ]; 
 

 
    // array to store result 
 
    result = []; 
 
    // store flags 
 
    flags = []; 
 

 
    for (i=0; i<data.length;i++) { 
 
     // dont run the rest of the loop if we already have this timestamp 
 
     if (flags[data[i].timestamp]) continue; 
 

 
     // if we didn't have the flag stored, then we need to record it in the result 
 
     result.push(data[i]); 
 

 
     // if we don't yet have the flag, then store it so we skip it next time 
 
     flags[data[i].timestamp] = true; 
 
    } 
 

 
    // stringify the result so that we can display it in an alert message 
 
    alert(JSON.stringify(result))

0

Почему вы читаете JSon файл с fs.readFile? Просто требуйте этого.

Фильтрация сама работа:

var arr = require('./file.json') 

var tester = [] 
var result = [] 

arr.forEach(function(el){ 
    if(tester.indexOf(el.timestamp) === -1) { 
    tester.push(el.timestamp) 
    result.push(el) 
    } 
}) 
Смежные вопросы