[英]How to get array of objects by object and arrays in javascript
[英]How to get the last N objects before a certain object in a Javascript array?
我正在嘗試在Javascript中實現無限加載項目。 就像在您喜歡的消息傳遞應用程序中滾動消息時所獲得的效果一樣。 我有一個像這樣的大陣列(+1000個對象):
var array = [
{ id : 1, text: "First"},
{ id : 2, text: "Second"},
{ id : 3, text: "Third"},
{ id : 4, text: "Forth"},
{ id : 5, text: "Fifth"},
{ id : 6, text: "Sixth"},
{ id : 7, text: "Seventh"},
...
];
現在我想一次只加載10個項目。 例如,我只顯示ID為30
到39
。 現在用戶希望在30
之前看到這些項目。 在id為30
對象之前選擇最后10個項目的最佳方法是什么? 如前所述,陣列的大小很大,所以性能在這里很重要。
上面的例子只是一個例子。 我應該能夠根據需要一次多次過濾我的數組10個項目。
我想要實現的是加載一個大陣列,但不是一次性加載。 我想一次加載10個項目。 我正在跟蹤我的過濾數組中的第一個對象(例如30
),然后我想在該特定對象之前獲取最后10個對象。
這是我的觀點:
<div ng-repeat="message in messages" class="message-wrapper">
// Show content of message
</div>
現在我最初在消息中顯示最后10項
$scope.init = function(){
var messages = Database.AllMessages(); // This function returns all my messages
$scope.messages = messages.length > 10 ? messages.slice(-10) : messages;
}
現在假設此函數返回的項目是Id為30
到39
。 用戶向上滾動並希望在30
之前看到消息。 那么如何過濾AllMessages()
返回的整個數組以獲得30
消息之前的10個最后一項?
提前感謝任何見解。
您希望盡可能高效地查詢數據源。 確保數組首先按id排序:
array.sort(function(a, b) {
if (a.id === b.id) return 0;
if (a.id > b.id) return 1;
return -1;
});
然后,可以執行二進制搜索以查找您要查找的元素的索引:
var search = function(arr, val) {
if (arr.length === 0) {
return -1;
}
var max = arr.length - 1, min = 0;
while (max !== min) {
var index = Math.floor((max + min) / 2);
if (arr[index].id === val) {
return index;
}
else if (arr[index].id < val) {
min = index;
}
else {
max = index;
}
}
return arr[index].id === val ? index : -1;
}
// find index of element with desired id.
var index = search(array, 30);
一旦我們知道索引,我們只需選擇索引之前/之后的元素:
var rangeMin = index - 10; // Inclusive. 10 is the maximum number of elements you want to render.
var rangeMax = index; // Not inclusive.
if (rangeMin < 0) { rangeMin = 0; }
if (rangeMax > array.length) { rangeMax = array.length; }
var elementsToRender = array.slice(rangeMin, rangeMax);
elementsToRender
現在將包含您要渲染的所有元素。
現在讓我們說這個函數返回的項是Id為30到39的項。用戶向上滾動並希望看到30之前的消息。那么如何過濾AllMessages()返回的整個數組來獲得10 30條消息之前的最后一項?
(...)我的觀點應該顯示項目20至39
假設allMessages
包含所有消息(非常大的數組)。
假設ctrl
是一個控制器實例
假設ctrl.messages
包含當前顯示的項目。
假設currentIndex
為30
假設stepSize
為10
然后,以下代碼將messages
擴展為包含項目20到39,並將currentIndex
設置為20:
currentIndex -= stepSize; // the new first message will have index 20
var extraItems = allMessages.slice(currentIndex, currentIndex+stepSize);
Array.prototype.push.apply(extraItems, ctrl.messages); // append ctrl.messages to extraItems
ctrl.messages = extraItems;
有關Array.prototype.push.apply
更多信息,請參閱Mozilla (向下滾動到'合並兩個數組')。
這是一個小應用程序來演示它(你必須添加邏輯來保護用戶跨越數組邊界):
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function() {
var ctrl = this;
var allMessages = Database.AllMessages();
var stepSize = 10;
var currentIndex = allMessages.length - stepSize;
// show the last 10 messages
ctrl.messages = allMessages.length > 10 ? allMessages.slice(-10) : allMessages;
// show ten more messages
ctrl.showMore = function () {
currentIndex -= stepSize;
var extraItems = allMessages.slice(currentIndex, currentIndex+stepSize);
Array.prototype.push.apply(extraItems, ctrl.messages);
ctrl.messages = extraItems;
};
});
</script>
</head>
<body ng-app="myApp">
<div ng-controller="MyController as ctrl">
<table>
<tr ng-repeat="message in ctrl.messages"><td>{{message.text}}</td></tr>
</table>
<button ng-click="ctrl.showMore();">show more</button>
</div>
</body>
</html>
您可以嘗試使用以下代碼獲取id為30的對象而不使用循環:
var array = [
{ id : 1, text: "First"},
{ id : 2, text: "Second"},
{ id : 3, text: "Third"},
{ id : 4, text: "Forth"},
{ id : 5, text: "Fifth"},
{ id : 6, text: "Sixth"},
{ id : 7, text: "Seventh"}
];
var result = $.grep(array, function(e){ return e.id == 5; });
console.log(result);
在id為30的對象之前選擇最后10個項目的最佳方法是什么?
var index = 30;
var count = 10;
// 10 items before 30 :
array.slice(index-count, index);
我知道我做的這件事對某人有幫助。 這是相關的部分:
$('button.getResult').on('click', function(e) {
e.preventDefault();
var limit = $('input.getResult').val();
if (limit != '' && !isNaN(limit)) {
var dots = $('ul li');
if (dots.length > limit) {
//show the limit as group
var foundSelected = false;
var counter = 0;
for (var i = dots.length - 1; i >= 0; i--) {
dots.eq(i).addClass('group');
dots.eq(i + parseInt(limit)).removeClass('group');
counter++;
if (i == $('li.selected').index()) {
foundSelected = true;
};
if (foundSelected && counter >= limit) {
i = -1;
};
};
} else {
//show all as group
dots.addClass('group');
};
};
return false;
});
dots
基本上就是你的數組,第一個條件就是檢查以確保你想要的結果數小於數組的長度。 然后通過數組執行循環(在我的情況下向后)檢查重要項目。 如果我找到它,我將布爾值更改為true。
另外,我將每個標記為我迭代時選擇的,如果所選索引超出了分頁限制,則刪除所選標記(以保持分頁)。 一旦我找到了重要的項目並且標記了重要項目之后的正確項目數量,我就會停止循環。
當然,您可能無法在您的案例中標記事物,但我認為您可以從中獲得一些靈感。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.