簡體   English   中英

在Javascript中改進數組轉換

[英]Improve Array transformation in Javascript

假設我有一個如下所示的輸入數組

var inputArray = [
    {a: 1, b: 1, c: 1, d: 1, value: 1, rank: 1},
    {a: 1, b: 1, c: 1, d: 1, value: 2, rank: 2},
    {a: 1, b: 1, c: 1, d: 1, value: 3, rank: 3},
    {a: 1, b: 1, c: 1, d: 1, value: 4, rank: 4},
    {a: 1, b: 1, c: 1, d: 1, value: 5, rank: 5},
    {a: 1, b: 2, c: 1, d: 1, value: 1, rank: 1},
    {a: 1, b: 2, c: 1, d: 1, value: 2, rank: 2},
    {a: 1, b: 2, c: 1, d: 1, value: 3, rank: 3},
    {a: 1, b: 2, c: 1, d: 1, value: 4, rank: 4},
    {a: 1, b: 2, c: 1, d: 1, value: 5, rank: 5}
]

我想我的轉變inputArray以下outputArray

var outputArray = [
    {
        a: 1,
        b: 1,
        c: 1,
        d: 1,
        values:{
            "1":{value: 1},
            "2":{value: 2},
            "3":{value: 3},
            "4":{value: 4},
            "5":{value: 5}
        }
    },
    {
        a: 1,
        b: 2,
        c: 1,
        d: 1,
        values:{
            "1":{value: 1},
            "2":{value: 2},
            "3":{value: 3},
            "4":{value: 4},
            "5":{value: 5}
        }
    }
]

這意味着,我需要為abcd相同屬性創建一個字典,其中屬性rank的值是字典的鍵,字典的值是唯一屬性為valueobject

我們假設inputArray不會根據abcd的組合進行排序。 所以,我的方法是這樣的,

 (function(){ var inputArray = [ {a: 1, b: 1, c: 1, d: 1, value: 1, rank: 1}, {a: 1, b: 1, c: 1, d: 1, value: 2, rank: 2}, {a: 1, b: 1, c: 1, d: 1, value: 3, rank: 3}, {a: 1, b: 1, c: 1, d: 1, value: 4, rank: 4}, {a: 1, b: 1, c: 1, d: 1, value: 5, rank: 5}, {a: 1, b: 2, c: 1, d: 1, value: 1, rank: 1}, {a: 1, b: 2, c: 1, d: 1, value: 2, rank: 2}, {a: 1, b: 2, c: 1, d: 1, value: 3, rank: 3}, {a: 1, b: 2, c: 1, d: 1, value: 4, rank: 4}, {a: 1, b: 2, c: 1, d: 1, value: 5, rank: 5} ] var temp = inputArray.sort(function(valA, valB){ if(valA.a === valB.a){ if(valA.b === valB.b){ if(valA.c === valB.c){ return valA.d < valB.d; } return valA.c < valB.c; } return valA.b < valB.b; } return valA.a < valB.a; }); var outputArray = [], currentIndex = 0; for(var i = 0; i < inputArray.length; i++){ if(i > 0 && isConfigurationSame(inputArray[i], inputArray[i-1])){ outputArray[currentIndex-1].values[inputArray[i].rank] = { value: inputArray[i].value } } else{ outputArray.push(mapToOutputArrayObject(inputArray[i])); currentIndex++; } } console.log(outputArray); function isConfigurationSame(A, B) { return Aa === Ba && Ab === Bb && Ac === Bc && Ad === Bd; } function mapToOutputArrayObject(val){ var row = {}; row['a'] = val.a; row['b'] = val.b; row['c'] = val.c; row['d'] = val.d; row['values'] = {}; row.values[val.rank] = { value: val.value } return row; } }()); 

但問題是,如果輸入數組的長度很大,這個東西真的會有更多的時間。 這種多標准排序也需要很長時間。

是否有更好的方法可以用更少的時間更有效地完成結果?

感謝您的時間和耐心。

更新: abcd可以是整數或null

您可以創建一個哈希表並根據a,b,c和d生成唯一鍵:

const hash = {};

for(const { a, b, c, d, value, rank } of array) {
  const key = JSON.stringify([a, b, c, d]); // generate a unique, but not random key
  if(hash[key]) { // check if it already exists,
   hash[key].values[rank] = value; // merge
  } else {
   hash[key] = { // create a new entry
     a, b, c, d,
     values: { [rank]: value },
   };
  }
}

const result = Object.values(hash); // turn the object into an array

那就是O(n),它比任何.sort實現的時間復雜度更好(但只有當a,b,c和d可序列化時才有效(如本例所示))。

您可以獲取一個Map和一組分組鍵,並收集每個組的值。

 var array = [{ a: 1, b: 1, c: 1, d: 1, value: 1, rank: 1 }, { a: 1, b: 1, c: 1, d: 1, value: 2, rank: 2 }, { a: 1, b: 1, c: 1, d: 1, value: 3, rank: 3 }, { a: 1, b: 1, c: 1, d: 1, value: 4, rank: 4 }, { a: 1, b: 1, c: 1, d: 1, value: 5, rank: 5 }, { a: 1, b: 2, c: 1, d: 1, value: 1, rank: 1 }, { a: 1, b: 2, c: 1, d: 1, value: 2, rank: 2 }, { a: 1, b: 2, c: 1, d: 1, value: 3, rank: 3 }, { a: 1, b: 2, c: 1, d: 1, value: 4, rank: 4 }, { a: 1, b: 2, c: 1, d: 1, value: 5, rank: 5 }], keys = ['a', 'b', 'c', 'd'], result = [], map = new Map; array.forEach(o => { var key = keys.map(k => o[k]).join('|'), temp = map.get(key); if (!temp) { map.set(key, temp = Object.assign(...keys.map(k => ({ [k]: o[k] })), { values: {} })); result.push(temp); } temp.values[o.rank] = { value: o.value }; }); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

下面是使用Set,Map和const方法構建Values對象的方法。

 var inputArray = [ {a: 1, b: 1, c: 1, d: 1, value: 1, rank: 1}, {a: 1, b: 1, c: 1, d: 1, value: 2, rank: 2}, {a: 1, b: 1, c: 1, d: 1, value: 3, rank: 3}, {a: 1, b: 1, c: 1, d: 1, value: 4, rank: 4}, {a: 1, b: 1, c: 1, d: 1, value: 5, rank: 5}, {a: 1, b: 2, c: 1, d: 1, value: 1, rank: 1}, {a: 1, b: 2, c: 1, d: 1, value: 2, rank: 2}, {a: 1, b: 2, c: 1, d: 1, value: 3, rank: 3}, {a: 1, b: 2, c: 1, d: 1, value: 4, rank: 4}, {a: 1, b: 2, c: 1, d: 1, value: 5, rank: 5} ]; const getValueObject = (a,b,c,d, arr) => { let obj = {}; arr.filter(i => ia === a && ib === b && ic ===c && id === d) .forEach(item => obj[item.value] = item.rank); return obj; }; // Get a set based on the key a,b,c,d let newArray = [...new Set(inputArray.map(({a,b,c,d}) => `${a},${b},${c},${d}`))] .map(item => { let [a,b,c,d] = item.split(',').map(i => parseInt(i)); // filter and add return { a: a, b: b, c: c, d: d, values: getValueObject(a,b,c,d, inputArray) }; }); console.log(newArray); 

這是另一種選擇,首先按abcd分組。 然后映射每個組,轉換valuerank

 var inputArray = [{a: 1, b: 1, c: 1, d: 1, value: 1, rank: 1}, {a: 1, b: 1, c: 1, d: 1, value: 2, rank: 2}, {a: 1, b: 1, c: 1, d: 1, value: 3, rank: 3}, {a: 1, b: 1, c: 1, d: 1, value: 4, rank: 4}, {a: 1, b: 1, c: 1, d: 1, value: 5, rank: 5}, {a: 1, b: 2, c: 1, d: 1, value: 1, rank: 1}, {a: 1, b: 2, c: 1, d: 1, value: 2, rank: 2}, {a: 1, b: 2, c: 1, d: 1, value: 3, rank: 3}, {a: 1, b: 2, c: 1, d: 1, value: 4, rank: 4}, {a: 1, b: 2, c: 1, d: 1, value: 5, rank: 5}]; function groupBy(array, callback) { return array.reduce((groups, item, ...args) => { const key = callback(item, ...args), group = groups[key] || (groups[key] = []); group.push(item); return groups; }, {}); }; console.log( Object .values( groupBy(inputArray, ({a, b, c, d}) => [a, b, c, d]) ) .map(group => { const {a, b, c, d} = group[0], values = {}; group.forEach(({value, rank}) => values[rank] = {value}); return {a, b, c, d, values}; }) ); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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