我正在呈现本地JSON数据(“类别”),并且正在显示重复的数据。我正在尝试将.filter()
与其他两种方法(.sort()
和.map()
)一起使用,但无法删除重复项。我的代码中有东西看起来不对吗?
var testjson = {
"d": {
"results": [{
"Title": "Aardvark",
"Category": "Animals",
"Description": "My Test description",
"TopTrainingCourse": false,
"ID": 1,
"Modified": "2019-03-05T20:13:46Z",
"Created": "2019-03-05T20:13:36Z"
}, {
"Title": "Red Panda",
"Category": "Animals",
"Description": "Donec id dictum sem",
"TopTrainingCourse": true,
"ID": 10,
"Modified": "2019-03-06T21:08:25Z",
"Created": "2019-03-06T21:08:25Z"
}, {
"Title": "Tennis",
"Category": "Sports",
"Description": "Mauris sagittis ligula",
"TopTrainingCourse": true,
"ID": 11,
"Modified": "2019-03-06T21:08:35Z",
"Created": "2019-03-06T21:08:35Z"
}]
}
}
loadAllCourses() {
let jsonRes = testjson.d.results
.filter((elem, index, self) => {
return (index === self.indexOf(elem));
})
.sort(function(a,b) { // sorts alphabetically
return (a.Category > b.Category) ? 1 : ((b.Category > a.Category) ? -1 : 0)
})
.map(x => {
return {
"Category": x.Category,
"Title": x.Title
}
});
let curIndex = 0;
$.each(jsonRes, function(idx, val) {
$(".form-control").append("<option><div data-toggle=\"modal\" data-target=\"#modal-id\">" + val.Category + "</div></option>") // dropdown
答案 0 :(得分:0)
answer of undefined(虽然很简单)循环的次数超过了必要。
filter
遍历列表。 (1次完整迭代)indexOf
在映射值中搜索特定值。 (部分迭代等于列表中的项目数量)使用示例数据(3个元素),您最终迭代了相同的列表1 + 3 + 3 * 0.5 = 5.5次。 (对于indexOf
使用平均0.5次迭代)。让我为您扩大清单的范围。假设您有10个项目的清单。现在,您要遍历列表1 + 10 + 10 * 0.5 = 16次。可以通过事先进行类别映射并每次都引用相同的列表来减少这种情况。
var testjson = { "d": { "results": [{ "Title": "Aardvark", "Category": "Animals", "Description": "My Test description", "TopTrainingCourse": false, "ID": 1, "Modified": "2019-03-05T20:13:46Z", "Created": "2019-03-05T20:13:36Z" }, { "Title": "Red Panda", "Category": "Animals", "Description": "Donec id dictum sem", "TopTrainingCourse": true, "ID": 10, "Modified": "2019-03-06T21:08:25Z", "Created": "2019-03-06T21:08:25Z" }, { "Title": "Tennis", "Category": "Sports", "Description": "Mauris sagittis ligula", "TopTrainingCourse": true, "ID": 11, "Modified": "2019-03-06T21:08:35Z", "Created": "2019-03-06T21:08:35Z" }] } }
console.log(
testjson.d.results
.filter(
function (elem, index) { return index === this.indexOf(elem.Category) },
testjson.d.results.map(el => el.Category) // <= executes only once
)
);
使用上述代码将迭代次数减少为1 + 1 + 10 * 0.5 = 7次(对于10个列表)。
但是,使用查找对象可以更快地完成此操作。
var testjson = { "d": { "results": [{ "Title": "Aardvark", "Category": "Animals", "Description": "My Test description", "TopTrainingCourse": false, "ID": 1, "Modified": "2019-03-05T20:13:46Z", "Created": "2019-03-05T20:13:36Z" }, { "Title": "Red Panda", "Category": "Animals", "Description": "Donec id dictum sem", "TopTrainingCourse": true, "ID": 10, "Modified": "2019-03-06T21:08:25Z", "Created": "2019-03-06T21:08:25Z" }, { "Title": "Tennis", "Category": "Sports", "Description": "Mauris sagittis ligula", "TopTrainingCourse": true, "ID": 11, "Modified": "2019-03-06T21:08:35Z", "Created": "2019-03-06T21:08:35Z" }] } }
console.log(
testjson.d.results
.filter(function (elem) {
return !this[elem.Category] && (this[elem.Category] = true);
}, {})
);
上面的方法仅通过数组本身循环一次,然后使用查找对象存储和检查数组中其他元素的存在。这样可以将迭代次数减少到1次。请记住,上述方法的确使用普通的JavaScript对象。这意味着类别不能包含保留属性,例如constructor
。如果这是一个问题,则可以在检查过程中为类别添加前缀或后缀。这是一个示例:
!this['_!!_' + elem.Category] && (this['_!!_' + elem.Category] = true)
请注意,上面function
关键字的使用是有意的。 Arrow function don't have their own this
binding,因此不能与filter
中的第二个参数结合使用方法。