簡體   English   中英

是否可以清空空值數組但在 JavaScript 中保持鍵不變?

[英]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。

有沒有辦法在不重新鍵入的情況下剔除空數組? 因為我感覺內存有問題,尤其是當我們進入更高的范圍時。

這是該項目的前端視圖的片段:

this.quantities 數組

我知道我可以重構我的代碼以使用引用對象 - 但正如業務的性質一樣 - 我沒有很多時間來重構和查找這些數量鍵在整個項目中交織在一起。

我正在使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM