我正在使用angular4。我需要显示一个包含唯一值的列表。
访问API时,我得到一个数组,从那个数组我需要只显示唯一数据。我将以特定的时间间隔访问该API,并且只有在存在新数据时才需要更新列表。
response= [{"id":"0DRDCH03DR51GGJGJNP80F7XZ8","value":"36af1784bec4_566601260"},{"id":"0DRDCFYGM2CAHAXYK96BPT9RHV","value":"36af1784bec4_566601140"},...]
listData = [];
for(let data of response) {
let tempValue = {id: '', time: ''};
let value = data.value.split('_')
if (value.length==2) {
if(value[value.length-1].length==2) {
tempValue.id = value[0];
tempValue.time = value[1];
}
let isPresent = false;
if(this.listData.length>0){
for(let value of this.listData){
if(value.time===tempValue.time){
isPresent = true;
}
}
}
if(!isPresent) {
this.listData.push(tempValue);
}
}
}
最终的listData
listData = [{id:'36af1784bec4', time: '566601140'},...]
上面的函数确实给了我一个唯一的listData
数组。我尝试使用array.filter
和new Set
但无法达到预期效果。
我想知道是否有一种有效的方法可以做到这一点。
答案 0 :(得分:2)
您可以通过以下代码删除副本。
var obj = {};
for ( var i=0, len=response.length; i < len; i++ )
obj[response[i]['id']] = response[i]; // if id Duplicate otherwise use value if the check on value.
response = new Array();
for ( var key in obj )
response.push(obj[key]);
console.log(response); // listData
修改强>
如果你想对你的道具进行全面检查,那么你可以选择这个
function removeDuplicates(myArr, prop) {
return myArr.filter((obj, pos, arr) => {
return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos;
});
}
console.log(removeDuplicates(response,['id','value'])); // for id or value use only 'id' or 'value' in second parameter.
答案 1 :(得分:1)
我认为这样做
for(let data of response) {
if(!this.listData.find((ldata) => data.value.substring(data.value.lastIndexOf('_')+1) === ldata.time)) {
let tempValue = {id: '', time: ''};
let value = data.value.split('_')
if (value.length==2) {
if(value[value.length-1].length==2) {
tempValue.id = value[0];
tempValue.time = value[1];
}
this.listData.push(tempValue);
}
}
}
答案 2 :(得分:1)
您也可以通过JSON.stringify
以下对象执行此操作:
let response = [{
"id": "0DRDCH03DR51GGJGJNP80F7XZ8",
"value": "36af1784bec4_566601260"
}, {
"id": "0DRDCFYGM2CAHAXYK96BPT9RHV",
"value": "36af1784bec4_566601140"
}, {
"id": "0DRDCH03DR51GGJGJNP80F7XZ8",
"value": "36af1784bec4_566601260"
}]
let o = response.reduce((acc, cv) => {
if (!acc[JSON.stringify(cv)]) {
acc[JSON.stringify(cv)] = true; //something non-falsy
}
return acc;
}, {});
let res = Object.keys(o).map(x => JSON.parse(x));
console.log(res);
修改强> 正如user3297291指出
可能有助于注意JSON.stringify({a:1,b:2})!== JSON.stringify({b:2,a:1})
因此,上述情况将失败。
更优化的解决方案是
let response = [{
"id": "0DRDCH03DR51GGJGJNP80F7XZ8",
"value": "36af1784bec4_566601260"
}, {
"id": "0DRDCFYGM2CAHAXYK96BPT9RHV",
"value": "36af1784bec4_566601140"
}, {
"id": "0DRDCH03DR51GGJGJNP80F7XZ8",
"value": "36af1784bec4_566601260"
}];
let o = response.reduce((acc, cv) => {
if (!acc[cv.value]) {
acc[cv.value] = true; //something non-falsy
}
return acc;
}, {});
let res = Object.keys(o).map(x => {
let t = x.split('_');
return {
id: t[0],
time: t[1]
};
});
console.log(res);
答案 3 :(得分:1)
对于优化解决方案(仅循环一次,即O(n)) 使用object属性来检查属性是否已经添加,通过这种方式,您将避免循环以查找是否已添加属性。
以下是示例解决方案
let response = [{
"id": "0DRDCH03DR51GGJGJNP80F7XZ8",
"value": "36af1784bec4_566601260"
}, {
"id": "0DRDCH03DR51GGJGJNP80F7XZ8",
"value": "36af1784bec4_566601260"
}, {
"id": "0DRDCFYGM2CAHAXYK96BPT9RHV",
"value": "36af1784bec4_566601140"
}],
listData = [],
tempObj = {};
for (let data of response) {
let value = data.value.split('_');
if (!tempObj.hasOwnProperty(value[1])) {
tempObj[data.value[1]] = "";
listData.push({
id: value[0],
time: value[1]
});
}
}
console.log(listData);
&#13;
更新:根据评论,仅检查重复的时间值
答案 4 :(得分:0)
您可以使用map
来收集ID,然后使用filter
删除重复项:
const response= [{"id":"0DRDCH03DR51GGJGJNP80F7XZ8","value":"36af1784bec4_566601260"},{"id":"0DRDCFYGM2CAHAXYK96BPT9RHV","value":"36af1784bec4_566601140"}];
const ids = response.map(it => it.value.split('_')[0]).filter((it, i, arr) => i === arr.indexOf(it))
console.log(ids);
或使用reduce
:
const response= [{"id":"0DRDCH03DR51GGJGJNP80F7XZ8","value":"36af1784bec4_566601260"},{"id":"0DRDCFYGM2CAHAXYK96BPT9RHV","value":"36af1784bec4_566601140"}];
const ids = response.reduce((acc, it) => {
const id = it.value.split('_')[0];
return acc.includes(id) ? acc : [...acc, id];
}, []);
console.log(ids);
答案 5 :(得分:0)
JavaScript的最新版本允许对对象结构的依赖保持不变...因此,我们现在可以依靠对两个字符串进行字符串化和比较:
arr = [{object}, {object2}, {etc...}]
test = JSON.stringify(obj);
for ( let i = 0, j = arr.length; i < j; i++ ) {
let testAgainst = JSON.stringify(arr[i]);
if (test === testAgainst) {
console.log('matches');
} else {
console.log('no match');
}
}
所以有一个对象数组:
很有帮助,因为您不需要知道键名。它只适用于任何对象类型...
{{1}}
现在您将匹配两个字符串。如果我缺少什么,请发表评论。