[英]How to create an object from the matches of multiple arrays
給定array1
和array2
我應該創建一個對象,其中的屬性和值來自兩個數組之間的交集匹配。
function objOfMatches(array1, array2, cb) {
var obj = {};
var newArray1 = array1.map(cb);
for (let i = 0; i < newArray1.length; i++) {
if( !(array2.indexOf(newArray1[i]) == -1) ) {
obj[newArray1[i].toLowerCase()] = newArray1[i];
}
}
return obj;
}
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));
// should log: { hi: 'HI', bye: 'BYE', later: 'LATER' }
有沒有比這個實現更好或更簡潔的寫法?
很不清楚這個函數應該做什么,這使得它很難閱讀。 相反,您應該將任務分開:
const intersection = (a, b) => a.filter(it => b.includes(it));
const toMap = (values, mapper) => Object.assign({}, ...values.map(value => ({ [mapper(value)]: value })));
const matches = intersection(array1.map(it => it.toUpperCase()), array2);
const result = toMap(matches, value => value.toLowerCase());
您可以使用reduce()
構建一個對象,只在找到匹配項的地方添加鍵。
function objOfMatches(array1, array2, cb) { return array1.reduce((obj, item) => { if (array2.includes(cb(item))) obj[item] = cb(item) return obj }, {}) } console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));
這很簡單,但它會有 O(n²) 行為,因為includes
會通過array2
查找array1
中的每個項目。 這對於小列表可能無關緊要,但如果列表很大,則可能值得進行某種散列(如Set
或對象),以便為您提供對array2
的恆定時間查找。
就像是:
function objOfMatches(array1, array2, cb) { let set = new Set(array2) return array1.reduce((obj, item) => { if (set.has(cb(item))) obj[item] = cb(item) return obj }, {}) } console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));
您可以使用一個Set
並為一個新對象映射公共部分。
這種方法需要兩個循環,一個用於每個數組。
function objOfMatches(array1, array2) { var s = new Set(array1); return Object.assign(...array2.map(v => s.has(v) && { [v.toLowerCase()]: v })); } console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'].map(s => s.toUpperCase()), ['HI', 'Howdy', 'BYE', 'LATER', 'hello']));
您可以使用即將推出的fromEntries
。 一個巨大的警告—— 根據 MDN ,當前的瀏覽器兼容性只是 Firefox atm。
但是:簡單地映射兩個數組以合並它們,然后從該合並數組上的fromEntries
為您提供對象。
function objOfMatches(arr1, arr2) { const merged = arr1.map((el, i) => [el, arr2[i]]); return Object.fromEntries(merged); } const result = objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello']); console.log(result);
你可以試試這個
function objOfMatches(array1, array2, cb) { return array1.reduce((op,cur,i)=>{ if(array2.includes(cur.toUpperCase())){ op[cur] = array2[i]; } return op; },{}) } console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'])); // should log: { hi: 'HI', bye: 'BYE', later: 'LATER' }
基於之前在http://csbin.io/callbacks練習中的自定義 forEach 和 Reduce
function forEach(array, callback) {
for(i = 0; i < array.length; i++){
callback(array[i])
}
}
function reduce(array, callback, initialValue) {
for(let i of array){
initialValue = callback(initialValue, i)
}
return initialValue
}
function objOfMatches(array1, array2, callback) {
let index = 0
return reduce(array1, (acc, el) => {
if(callback(el) == array2[index]){
acc[el] = array2[index]
}
index++
return acc
}, {})
}
如果您使用內置的 reduce 功能,您可以自動將索引傳遞給回調:
function objOfMatches(array1, array2, callback) {
return array1.reduce((acc, el, index) => {
if(callback(el) == array2[index]){
acc[el] = array2[index]
}
return acc
}, {})
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.