[英]Is it possible to empty an array of null values but keep the keys unchanged in JavaScript?
我有一個構造如下的數組:
目前,我嘗試過的所有解決方案都是相似的,例如:
this.quantities = this.quantities.filter(e => e.length);
然而,這些會繼續刪除所有空數組(根據需要)並重新設置數組,這是正常行為(不需要螞蟻),因此 500、1000、5000 變為 1、2 和 3。
有沒有辦法在不重新鍵入的情況下剔除空數組? 因為我感覺內存有問題,尤其是當我們進入更高的范圍時。
這是該項目的前端視圖的片段:
我知道我可以重構我的代碼以使用引用對象 - 但正如業務的性質一樣 - 我沒有很多時間來重構和查找這些數量鍵在整個項目中交織在一起。
我正在使用 VueJS & 這是我的方法:
this.quantities[ this.enter_qty ] = [];
this.quantities[ this.enter_qty ][ 0 ] = {
quantity: this.enter_qty,
item_description: null,
supplier_contact_id: null
};
//this.quantities = this.quantities.filter(e => e.length);
沒有一個最小的可重復示例,我只會編造一些東西,以便我可以進行測試。 因此,您有一個稀疏數組,並且您希望在剔除某些元素時保持其稀疏性,而不會遇到性能或內存問題。 以下是我可能會怎么做:
Object.keys(sparseArray).forEach(
k => filterCriterion(sparseArray[+k]) || delete sparseArray[+k]
);
其中sparseArray
是你的稀疏數組, filterCriterion()
是一個函數,如果元素應該被保留,則返回true
如果元素被剔除,則返回false
。
JavaScript 中的數組只是對象, Object.keys()
方法只會返回那些實際存在的索引,而會忽略數組中的“漏洞”。 您也可以直接編寫sparseArray.forEach()
代替Object.keys(sparseArray).forEach()
,但后者至少在一個流行的瀏覽器中存在一些性能問題,因為即使回調僅在非漏洞上調用,實現顯然仍然從0
計數。
無論如何,一旦你有了非孔鍵, filterCriterion(sparseArray[+k]) || delete sparseArray[+k]
如果過濾條件返回true
,則filterCriterion(sparseArray[+k]) || delete sparseArray[+k]
將短路,否則它將對相關元素調用delete
,這會在數組中戳出一個新孔。
的+
在+k
是在運行時不會嚴格必須的,但打字原稿變得有點不快關於索引到一個數組與string
的元素Object.keys()
的結果。 因此,將k
轉換為+k
顯式地將字符串強制為一個number
,這使編譯器感到滿意,即使運行時會將該數字強制為字符串以進行索引。 因此,如果需要,請省略+
。
讓我們測試一下:
const bigLength = 0xffffffff; // biggest possible array
const sparseArray = new Array<string[]>(bigLength);
// add ten elements
for (let i = 0; i < 10; i++) {
sparseArray[Math.floor(Math.random() * bigLength)] =
Math.random() < 0.5 ? [] : ["hello"];
}
console.log(sparseArray.length); // big length
console.log(Object.keys(sparseArray)); // only prints out up to ten keys, so it's sparse
這里我們有一個很大的length
數組,但它只有(最多)十個元素。 讓我們想出一種打印出來的方法,只需將非孔復制到一個新的普通對象並對其進行字符串化:
function sparseArrayToObject<T>(arr: T[]): { [k: number]: T } {
const ret: { [k: number]: T } = {};
Object.keys(arr).sort().forEach(k => ret[+k] = arr[+k]);
return ret;
}
console.log(JSON.stringify(sparseArrayToObject(sparseArray)))
// {"769691472":["hello"],"1142335691":["hello"],"1663136124":[],
// "1797609912":["hello"],"2067316024":["hello"],
// "2440181807":["hello"],"2467909915":["hello"],
// "2559556024":[],"2877791549":[],"3996739691":[]}
這僅打印出(最多)十個元素,它們是一些隨機鍵。 現在我們想剔除空數組 ( []
) 並留下非空數組 ( ["hello"]
)。 開始了:
// cull empty elements from sparse array
Object.keys(sparseArray).forEach(k => sparseArray[+k].length || delete sparseArray[+k]);
這在我的環境中幾乎不需要時間,因此性能應該不是問題。 如果您將其切換為sparseArray.forEach((v, i, a) => v.length || delete a[i])
您將很難等待編譯器計數到 40 億,即使它只運行非孔的回調。
嗯,有效果嗎? 讓我們來看看:
console.log(JSON.stringify(sparseArrayToObject(sparseArray)))
// {"769691472":["hello"],"1142335691":["hello"],"1797609912":["hello"],
// "2067316024":["hello"],"2440181807":["hello"],"2467909915":["hello"]}
在我看來很好。
好的,希望有幫助; 祝你好運!
有沒有辦法在不重新鍵入的情況下剔除空數組?
簡短回答:不,沒有。
至少不是數組。
在 javascript(以及許多其他語言)中,數組必須包含每個索引的值。
編輯:我錯了。 數組可以有空索引。 無論如何,以下解決方案應該有效。
如果我理解正確,您可能正在尋找Map 。 使用 Maps 可以刪除鍵/值對,而無需重新分配其他值。 因此,對於您的具體示例,您可以使用鍵 (Object.keys()) 將每個值分配給映射,但將那些空數組的值排除在外。 通過這種方式,您可以保留每個值的鍵,而不會浪費內存。
另一種解決方案是將數組存儲為對象。 因此,使用包含非空數組的數組鍵創建一個對象。
一個非常基本的例子是:
let arrayOfArrays = [
[1, 2, 3],
[],
[],
[1, 2],
[],
[3, 4, 5]
]
function cullArray(array) {
let obj = {};
for(let i of Object.keys(array)) {
if(array[i].length !== 0) {
obj[i] = array[i]
}
}
return obj;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.