2016-07-27 52 views
-1

我想修改一個Javascript數組,使具有相同值的指定屬性的元素以其他屬性保留爲逗號分隔字符串的方式合併到一個對象中,JSON字符串或數組。基本上,我想打開該:Javascript - 減少具有多鍵對象的數組

[ 
    { 
     "language" : "english", 
     "type" : "a", 
     "value" : "value1" 
    }, 
    { 
     "language" : "english", 
     "type" : "a", 
     "value" : "value2" 
    }, 
    { 
     "language" : "english", 
     "type" : "b", 
     "value" : "value3" 
    }, 
    { 
     "language" : "spanish", 
     "type" : "a", 
     "value" : "valor1" 
    } 
] 

成這樣:

[ 
    { 
     "language" : "english", 
     "type" : "a", 
     "value" : ["value1" , "value2"] // A Json string is welcome too 
    }, 
    { 
     "language" : "english", 
     "type" : "b", 
     "value" : "value3" 
    }, 
    { 
     "language" : "spanish", 
     "type" : "a", 
     "value" : "valor1" 
    } 
] 

我試圖迭代和濾波,然後upserted對象作爲片斷給出。但我不知道是否有更優雅的方式來做到這一點。

P.S ecmaScript6和其他JS庫的建議也歡迎。

var originalArray = [ 
 
\t { 
 
\t \t "language" : "english", 
 
\t \t "type" : "a", 
 
\t \t "value" : "value1" 
 
\t }, 
 
\t { 
 
\t \t "language" : "english", 
 
\t \t "type" : "a", 
 
\t \t "value" : "value2" 
 
\t }, 
 
\t { 
 
\t \t "language" : "english", 
 
\t \t "type" : "b", 
 
\t \t "value" : "value3" 
 
\t }, \t 
 
\t { 
 
\t \t "language" : "spanish", 
 
\t \t "type" : "a", 
 
\t \t "value" : "valor1" 
 
\t } 
 
]; 
 

 
var resultingArray = []; 
 

 
// iterate through the original array 
 
$.each(originalArray, function(i, val) { 
 
    // apply filter on key properties (i.e. language and type) 
 
    var result = resultingArray.filter(function(obj) { 
 
    return (obj.language === val.language && obj.type === val.type); 
 
    }); 
 
    // if a record exists, update its value 
 
    if (result.length === 1) { 
 
    result[0].value += (", " + val.value); 
 
    } 
 
    // else, add value 
 
    else if (result.length === 0) { 
 
    resultingArray.push(val); 
 
    } 
 
    // if multiple rows exist with same key property values... 
 
    else { 
 
    alert("Too many records with language '" + val.language + "' and type '" + val.type + "'"); 
 
    } 
 
}); 
 

 
console.log(JSON.stringify(resultingArray));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

+1

[這裏是我建議的解決方案(http://pastebin.com/bx66Vc5K),這取決於你認爲 「優雅」。代碼的問題在於運行在'O(N^2)'中,因爲'filter'函數在第一次迭代時運行一次,在第二次迭代中運行兩次,依此類推。這是沒有必要的。 –

+1

而[這裏](https://jsfiddle.net/Arnauld/0eyxbf70/)是我的,其中'value'總是一個數組。順便說一句:我認爲你的'alert()'語句永遠不會被觸發。如果您不想爲相同的鍵(語言+類型)使用相同的_value_兩次,則必須以不同的方式進行操作。 – Arnauld

+0

嘿,你的JS使用的是jQuery,爲什麼你不添加jQuery標籤?我學習並確保使用純JavaScript'forEach'來幫助你-_-! –

回答

0

這是你需要什麼?

var baseData= [ 
 
    { 
 
     "language" : "english", 
 
     "type" : "a", 
 
     "value" : "value1" 
 
    }, 
 
    { 
 
     "language" : "english", 
 
     "type" : "a", 
 
     "value" : "value2" 
 
    }, 
 
    { 
 
     "language" : "english", 
 
     "type" : "b", 
 
     "value" : "value3" 
 
    }, 
 
    { 
 
     "language" : "spanish", 
 
     "type" : "a", 
 
     "value" : "valor1" 
 
    } 
 
]; 
 

 
var newData = []; 
 
baseData.forEach(function(item, index) { 
 
    if (newData.length === 0) { 
 
    newData.push(item); 
 
    
 
    } else { 
 
    var dIndex = -1; 
 
    newData.forEach(function(itm, idx) { 
 
     if (item.language === itm.language && item.type === itm.type) dIndex = idx; 
 
    }); 
 
    
 
    if (dIndex !== -1) { 
 
     var oldValue = newData[dIndex].value; 
 
     
 
     if (typeof(oldValue).toString() === 'string') { 
 
     newData[dIndex].value = [oldValue, item.value]; 
 
     } 
 
    } else { 
 
     newData.push(item); 
 
    } 
 
    } 
 
}); 
 
console.log(newData);