[英]Javascript - denormalize JSON array using map function instead of nested for loop
I'm trying to get my head around map functions. 我正在努力使自己了解地图功能。 Here is my working code and output using a nested for loop: 这是我的工作代码,并使用嵌套的for循环输出:
var jsonsToAddTo = [
{'cat':'k1','key2':'a'},
{'cat':'k1','key2':'b'},
{'cat':'k2','key2':'a'},
{'cat':'k2','key2':'b'},
{'cat':'k3','key2':'a'}
]
var additionalData = [
{'pk':'k1','key3':'data1'},
{'pk':'k2','key3':'data2'},
{'pk':'k3','key3':'data3'},
]
// Adds a key value pair from sourceJson to targetJson based on a matching value
function denormalizeJsonOnKey(targetJsonArray,targetKeyToMatch, sourceJsonArray, sourceKeyToMatch, keyToAdd){
for(thisJson in targetJsonArray){
for(thatJson in sourceJsonArray){
if(targetJsonArray[thisJson][targetKeyToMatch]==sourceJsonArray[thatJson][sourceKeyToMatch]){
console.log('match');
targetJsonArray[thisJson][keyToAdd]=sourceJsonArray[thatJson][keyToAdd];
}
}
}
return targetJsonArray
}
console.log(denormalizeJsonOnKey(jsonsToAddTo,'cat',additionalData,'pk','key3'))
OUTPUT: OUTPUT:
[
{ cat: 'k1', key2: 'a', key3: 'data1' },
{ cat: 'k1', key2: 'b', key3: 'data1' },
{ cat: 'k2', key2: 'a', key3: 'data2' },
{ cat: 'k2', key2: 'b', key3: 'data2' },
{ cat: 'k3', key2: 'a', key3: 'data3' }
]
I can't figure out how to handle the nesting using a map function on an array. 我不知道如何使用数组上的map函数来处理嵌套。
Using ES6 can simplify using Array#find()
and Object#assign()
使用ES6可以简化使用Array#find()
和Object#assign()
var data = [ {'cat':'k1','key2':'a'}, {'cat':'k1','key2':'b'}, {'cat':'k2','key2':'a'}, {'cat':'k2','key2':'b'}, {'cat':'k3','key2':'a'} ] var data2 = [ {'pk':'k1','key3':'data1'}, {'pk':'k2','key3':'data2'}, {'pk':'k3','key3':'data3'}, ] const mergeData= (arr1, arr2, matchKey, filterKey, includeKey)=>{ arr1.forEach(o => { const newObj ={}; const match = arr2.find(e => e[filterKey] === o[matchKey]) newObj[includeKey] = match ? match[includeKey] : null; Object.assign(o, newObj); }); } mergeData(data, data2,'cat', 'pk', 'key3') console.log(data)
Here is a solution that takes advantage of map
and object spread to produce a new array with the desired key added into the target array's elements: 这是一个利用map
和对象扩展来产生一个新数组的解决方案,该数组将所需的键添加到目标数组的元素中:
var jsonsToAddTo = [ {'cat':'k1','key2':'a'}, {'cat':'k1','key2':'b'}, {'cat':'k2','key2':'a'}, {'cat':'k2','key2':'b'}, {'cat':'k3','key2':'a'} ] var additionalData = [ {'pk':'k1','key3':'data1'}, {'pk':'k2','key3':'data2'}, {'pk':'k3','key3':'data3'}, ] function denormalizeJsonOnKey(targetJsonArray,targetKeyToMatch, sourceJsonArray, sourceKeyToMatch, keyToAdd){ return targetJsonArray.map(thisJson => { const addObj = sourceJsonArray.find(thatJson => thatJson[sourceKeyToMatch] === thisJson[targetKeyToMatch]); return { ...thisJson, ...addObj ? {[keyToAdd]: addObj[keyToAdd]} : {}, } }); } console.log(denormalizeJsonOnKey(jsonsToAddTo, 'cat', additionalData, 'pk', 'key3'))
Note that this solution won't mutate the original array, so the jsonsToAddTo
variable will be the same after you invoke the function. 请注意,此解决方案不会jsonsToAddTo
原始数组,因此调用该函数后, jsonsToAddTo
变量将相同。 If you want to replace the original, you can always just re-assign it: 如果您想更换原件,可以随时重新分配它:
jsonsToAddTo = denormalizeJsonOnKey(jsonsToAddTo, 'cat', additionalData, 'pk', 'key3')
var targetJsonArray = jsonsToAddTo.map(function(json, index) {
additionalData.forEach(function(data) {
if (data.pk === json.cat) {
json.key3 = data.key3;
}
})
return json;
})
Try this, using maps
for both iteration, 尝试使用maps
进行两次迭代,
var jsonsToAddTo = [{'cat':'k1','key2':'a'},{'cat':'k1','key2':'b'}, {'cat':'k2','key2':'a'},{'cat':'k2','key2':'b'}, {'cat':'k3','key2':'a'}] var additionalData = [{'pk':'k1','key3':'data1'},{'pk':'k2','key3':'data2'},{'pk':'k3','key3':'data3'}, ] function denormalizeJsonOnKey(targetJsonArray,targetKeyToMatch, sourceJsonArray, sourceKeyToMatch, keyToAdd){ jsonsToAddTo.map((obj,index)=> { additionalData.map((o,idx)=> { if(obj[targetKeyToMatch]==o[sourceKeyToMatch]){ obj[keyToAdd]=o[keyToAdd]; } }) }) return jsonsToAddTo } console.log(denormalizeJsonOnKey(jsonsToAddTo,'cat',additionalData,'pk','key3'))
Rather than nesting loops here, which will iterate the entire additionalData
array for every entry in jsonsToAddTo
, I suggest building an object map of the additionalData
dataset once at the beginning, and then reference this within a .map on the target dataset: 而不是在这里筑巢循环,这将遍历整个additionalData
阵列中每个项目jsonsToAddTo
,我建议建立的一个对象映射additionalData
开头数据集一次 ,然后对目标数据集.MAP中引用这样的:
var jsonsToAddTo = [
{'cat':'k1','key2':'a'},
{'cat':'k1','key2':'b'},
{'cat':'k2','key2':'a'},
{'cat':'k2','key2':'b'},
{'cat':'k3','key2':'a'}
]
var additionalData = [
{'pk':'k1','key3':'data1'},
{'pk':'k2','key3':'data2'},
{'pk':'k3','key3':'data3'},
]
// Adds a key value pair from sourceJson to targetJson based on a matching value
function denormalizeJsonOnKey(targetJsonArray,targetKeyToMatch, sourceJsonArray, sourceKeyToMatch, keyToAdd){
// Build an object of items keyed on sourceKeyToMatch
const sourceJsonMap = sourceJsonArray.reduce((obj, item) => (obj[item[sourceKeyToMatch]]=item, obj), {});
return targetJsonArray.map(item => {
const targetValue = item[targetKeyToMatch];
if (sourceJsonMap.hasOwnProperty(targetValue)) {
item[keyToAdd] = sourceJsonMap[targetValue][keyToAdd];
}
return item;
});
}
console.log(denormalizeJsonOnKey(jsonsToAddTo,'cat',additionalData,'pk','key3'))
Doing it this way should be far more efficient, especially if the dataset you are working on is fairly large. 这样做的效率应该更高得多,尤其是当您正在处理的数据集相当大时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.