我有一些带有一些键和值的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 :(得分:5)
您可以将对象用作哈希表并检查。
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]);
}
}
答案 1 :(得分:3)
为什么你用fs.readFile读取json文件?只需要它。
过滤作业本身:
const arr = require('./file.json')
const tester = []
const result = []
arr.forEach(function(el) {
if (tester.indexOf(el.timestamp) === -1) {
tester.push(el.timestamp)
result.push(el)
}
})
<强>更新强> 优雅的解决方案使用 Array.prototype.reduce :
const result = arr.reduce(function(result, current) {
if (result.indexOf(current) === -1) result.push(current);
}, []);
<强>更新强> 大多数情况下效率最高:
const hashmap = {};
arr.forEach(el => {
if(!hash[el.timestamp]) hash[el.timestamp] = el;
})
const result = Object.values(hashmap);
<强>更新强> 对所有情况最有效和稳定。散列函数会在每种情况下引起碰撞的情况下,上层解决方案将非常低效。这个将是最稳定的一个:
const result = [];
arr.sort((a,b) => a.timestamp - b.timestamp);
arr.forEach(el => {
const last = result[result.length-1];
if (el.timestamp === last.timestamp) continue;
result.push(el);
});
答案 2 :(得分:1)
一种简单的方法是使用一组标志。肯定有更好的方法,但这是一个相当简单的方法,它应该适合你。
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))
答案 3 :(得分:0)
您可以使用reduce并获取唯一项
检查此代码段
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);
希望有所帮助