簡體   English   中英

如何從多個數組的匹配中創建一個對象

[英]How to create an object from the matches of multiple arrays

給定array1array2我應該創建一個對象,其中的屬性和值來自兩個數組之間的交集匹配。

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.

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