[英]Is it safe to join two arrays with for loop and findIndex in Javascript
我有以下代碼,它們將通過比較每個元素的id屬性來連接兩個數組。
//dummy test data var arrayA = [{ id: 0, data: "hello" }, { id: 1, data: "world" }, { id: 2, data: "!" }], arrayB = [{ id: 2, data2: "bbb" }, { id: 1, data2: "aaa" }, { id: 3, data2: "ccc" }]; (function(a, b) { for (var i in a) { var pos = b.findIndex(function(obj) { return a[i].id == obj.id; }); if (pos !== -1) { a[i] = $.extend({}, a[i], b[pos]); } else { //do something } } })(arrayA, arrayB); console.log(arrayA);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
如您所見,在Chrome開發工具中進行測試后,該代碼可以正常運行。 但是,ESLint不斷告訴我,循環中的函數可能導致錯誤的輸出( no-loop-func )。 因此,問題是,在Array.prototype.findIndex()
或find()
內部的匿名函數中使用循環變量是否安全? 如果沒有,代碼在什么情況下會出錯?
您所問的內容在您提到的文章中得到了解釋。 簡而言之:就您而言,這是安全的,但是如果您以后修改該代碼,則可能不會變得安全。
我建議將您的代碼重寫為兩個循環,因為它更易於理解,更安全且性能更高。
for (var i = 0; i < a.length; i++) {
var found = false;
for (var j = 0; j < b.length; j++)
if (a[i].id === b[j].id) {
Object.assign(a[i], b[j]);
found = true;
break;
}
if (!found)
...
}
沒有found
變量的替代方法(對我而言,這很hacky):
for (var i = 0; i < a.length; i++) {
for (var j = 0; j < b.length; j++)
if (a[i].id === b[j].id)
break;
if (j < b.length) {
// Found a match
Object.assign(a[i], b[j]);
...
} else {
...
}
}
代碼的簡單是重要的循環和嵌套函數通常傾向於perfromant少,可讀性和混亂(替他人或為你一段時間后)。
是可以安全使用循環變量在匿名函數內部
Array.prototype.findIndex()
或find()
? 如果沒有,代碼在什么情況下會出錯?
是的,它是安全的,這是因為傳遞給回調findIndex
被同步執行(同樣是真正find
)。 棉絨規則使因為在一般情況下,通過一些方法的回調函數可以異步調用,在這種情況下,這是一個問題的意義。 然后可以通過在塊范圍內聲明i
來解決該問題:
for (let i in a) {
這項更改甚至可能使您的案件變得無所適從。
請注意,您可以執行此工作而不必在每次迭代中都使用findIndex
(或find
)掃描b
數組,因此,如果要使用Map of,則可以使用O(n)而不是O(n²)時間復雜度運行某種。
同樣,通常不建議使用for...in
語法遍歷數組。 您可以使用forEach
數組方法。
以下是一些ES6代碼的外觀:
(function(a, b) {
const b_ids = new Map(b.map(obj => [obj.id, obj]));
a.forEach( (obj, i) => {
if (b_ids.has(obj.id)) {
a[i] = Object.assign({}, obj, b_ids.get(obj.id));
} else {
//do something
}
});
})(arrayA, arrayB);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.