I've been trying to merge data and get this result:
data = [{serviceID: 22, quantite: 120, typeConviveId: 6},
{serviceID: 23, quantite: 240, typeConviveId: 6},
{serviceID: 24, quantite: 100, typeConviveId: 7},
{serviceID: 25, quantite: 150, typeConviveId: 7}]
what needed at end :
result: [ { "22": "120", "23": "240", "typeConviveId": "6"},
{ "24": "100", "25": "150", "typeConviveId": "7" } ]
You can use a combination of Array.prototype.map, Array.prototype.filter and Array.prototype.reduce, along with a list of unique typeConviveId deduped using a Set with [...new Set(data.map(x=>x.typeConviveId))]:
const data = [{serviceID: 22, quantite: 120, typeConviveId: 6}, {serviceID: 23, quantite: 240, typeConviveId: 6}, {serviceID: 24, quantite: 100, typeConviveId: 7}, {serviceID: 25, quantite: 150, typeConviveId: 7}];
const result = [...new Set(data.map(x => x.typeConviveId))].map(
id => data
.filter(x => x.typeConviveId === id)
.reduce((acc, val) => {
return { ...acc,
[val.serviceID]: '' + val.quantite
}
}, {
typeConviveId: '' + id
})
);
console.log(result);
You can use array reduce & in the callback function use findIndex to get the object which has same typeConviveId. findIndex will return the index of the object which has same findIndex from the accumulator array which is represented by acc. In fiindIndex is -1 then create a new object with required keys and push it in the accumulator array. If there already exist an array with same typeConviveId then just update the object with new key
let data = [{
serviceID: 22,
quantite: 120,
typeConviveId: 6
},
{
serviceID: 23,
quantite: 240,
typeConviveId: 6
},
{
serviceID: 24,
quantite: 100,
typeConviveId: 7
},
{
serviceID: 25,
quantite: 150,
typeConviveId: 7
},
{
serviceID: 25,
quantite: 250,
typeConviveId: 7
}
]
let newData = data.reduce(function(acc, curr) {
let findIndex = acc.findIndex(function(item) {
return item.typeConviveId === curr.typeConviveId;
})
if (findIndex === -1) {
acc.push({
typeConviveId: curr.typeConviveId,
[curr.serviceID]: curr.quantite
})
} else {
acc[findIndex][curr.serviceID] = curr.quantite
}
return acc;
}, []);
console.log(newData)
The expected result have a problem. If there is a duplicate key for example suppose if the key like 22 i s repeated , then it will have the last value.
{
serviceID: 25,
quantite: 150,
typeConviveId: 7
},
{
serviceID: 25,
quantite: 250,
typeConviveId: 7
}
In this case serviceID in both object is 25, So its value will be 250. It will not have two keys with separate value
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I have an array of objects:
[
{ appleID: 13, bananaID: 55 },
{ appleID: 24, bananaID: 13},
{ appleID: 97, bananaID: 13},
{ appleID: 13, bananaID: 55 }
]
The result should look like this:
[
{ appleID: 13, bananaID: 55, count: 2 },
{ appleID: 24, bananaID: 13, count: 1},
{ appleID: 97, bananaID: 13, count: 1}
]
Count the number of identical elements by element === appleID && element === bananaID
You can use .reduce to aggregate your data by 2 things below:
The key idea is building the key with a format like const key = ${appleID}-${bananaID}
Use In terms of performance, you can use object to get the highest performance (Find just takes O(1))
const data = [
{ appleID: 13, bananaID: 55 },
{ appleID: 24, bananaID: 13},
{ appleID: 97, bananaID: 13},
{ appleID: 13, bananaID: 55 }
];
const result = data.reduce((acc, {appleID, bananaID}) => {
const key = `${appleID}-${bananaID}`
acc[key] ??= {appleID, bananaID, count: 0};
acc[key]["count"] += 1;
return acc;
}, {});
console.log(Object.values(result));
const data = [
{ appleID: 13, bananaID: 55 },
{ appleID: 24, bananaID: 13},
{ appleID: 97, bananaID: 13},
{ appleID: 13, bananaID: 55 }
]
function countNum(arr){
return arr.reduce((pre, item) => {
const hasItem = pre.find(subItem => subItem.appleID === item.appleID && subItem.bananaID === item.bananaID)
if(hasItem){
hasItem.count++
}else{
pre.push({...item, count: 1})
}
return pre
}, [])
}
console.log(countNum(data))
like this
function countNum(arr){
return arr.reduce((pre, item) => {
const hasItem = pre.find(subItem => subItem.appleID === item.appleID && subItem.bananaID === item.bananaID)
if(hasItem){
hasItem.count++
}else{
pre.push({...item, count: 1})
}
return pre
}, [])
}
I have an array of and array of objects similar to this :
const oldArray =[
[{'val': 12, 'rank':1},{'val': 122, 'rank':1},{'val': 112, 'rank':1}],
[{'val': 12, 'rank':2},{'val': 122, 'rank':2},{'val': 112, 'rank':2}],
[{'val': 12, 'rank':3},{'val': 122, 'rank':3},{'val': 112, 'rank':3}]
]
how can I retrieve the array that has the 'rank' values set to 3?
const newArray = [{'val': 12, 'rank':3},{'val': 122, 'rank':3},{'val': 112, 'rank':3}];
thanks in advance!
You could use Array.prototype.flat() with Array.prototype.filter() method to get the result.
const oldArray = [
[
{ val: 12, rank: 1 },
{ val: 122, rank: 1 },
{ val: 112, rank: 1 },
],
[
{ val: 12, rank: 2 },
{ val: 122, rank: 2 },
{ val: 112, rank: 2 },
],
[
{ val: 12, rank: 3 },
{ val: 122, rank: 3 },
{ val: 112, rank: 3 },
],
];
const ret = oldArray.flat().filter((x) => x.rank === 3);
console.log(ret);
Assuming all ranks within the inner arrays are the same you could use find() and check the rank of the first element within each array.
const oldArray = [
[{'val': 12, 'rank':1},{'val': 122, 'rank':1},{'val': 112, 'rank':1}],
[{'val': 12, 'rank':2},{'val': 122, 'rank':2},{'val': 112, 'rank':2}],
[{'val': 12, 'rank':3},{'val': 122, 'rank':3},{'val': 112, 'rank':3}],
];
const newArray = oldArray.find(([element]) => element.rank == 3);
console.log(newArray);
This answer uses destructuring to extract the first element of each inner array.
This answer will also throw an error if the inner array can be empty (accessing "rank" of undefined), which can be avoided by using optional chaining. eg. element?.rank == 3
I have an array and I need to filter out keys based on an input string. Only OLD_VAL is static, the rest are dynamic. I tried using the variable but it is not bringing that key
let input = VKORG,VTWEG,MATNR;
let arr = [
{
VKORG: 1100,
VTWEG: 10,
MATNR: 12,
RATE: 0.01,
VALUE: 1,
OLD_VAL: 12,
},
{
VKORG: 2100,
VTWEG: 99,
MATNR: 13,
RATE: 0.11,
VALUE: 11,
OLD_VAL: 12,
},
];
Output:
[
{
VKORG: "1100",
VTWEG: 10,
MATNR: "12",
OLD_VAL: 12,
},
{
VKORG: "2100",
VTWEG: 99,
MATNR: "13",
OLD_VAL: 12,
},
];
Code tried
let filterResults = results.map(({ OLD_VAL,input }) => ({ OLD_VAL, input }))
Assuming input is an array of strings, you can use Object.entries and create an object at each iteration consisting of the key-value pairs where keys are obtained from the input.
const input = ['VKORG', 'VTWEG', 'MATNR']
const arr = [{
VKORG: 1100,
VTWEG: 10,
MATNR: 12,
RATE: 0.01,
VALUE: 1,
OLD_VAL: 12,
},
{
VKORG: 2100,
VTWEG: 99,
MATNR: 13,
RATE: 0.11,
VALUE: 11,
OLD_VAL: 12,
}
]
const result = arr.map(el => Object.fromEntries(input.map(key => [key, el[key]]).concat([['OLD_VAL', el.OLD_VAL]])));
console.log(result);
If the input isn't an array of strings but is a string('VKORG,VTWEG,MATNR') then you can split it and use the above logic.
const input = 'VKORG,VTWEG,MATNR';
const inputArr = input.split(',');
const arr = [{
VKORG: 1100,
VTWEG: 10,
MATNR: 12,
RATE: 0.01,
VALUE: 1,
OLD_VAL: 12,
},
{
VKORG: 2100,
VTWEG: 99,
MATNR: 13,
RATE: 0.11,
VALUE: 11,
OLD_VAL: 12,
}
]
// using a spread operator instead of concat
const result = arr.map(el => Object.fromEntries([
...inputArr.map(key => [key, el[key]]), ['OLD_VAL', el.OLD_VAL]
]));
console.log(result);
You can do this with either way :
Good old for loop
const newArr = [];
for(let obj of arr) {
let newObj = {}
for(let key of input) {
console.log(key)
newObj[key] = obj[key]
}
newArr.push(newObj);
}
Or using map and reduce methods of the Array interface:
arr.map( e => input.reduce((acc, key) => {
acc[key] = e[key];
return acc;
},{}))
PS: dont forget that object keys are strings so your input variable should be :
const input = ['VKORG', 'VTWEG', 'MATNR']
I have an array that contains nested arrays.
The nested array can contain multiple objects.
const axisChoiceLoop = _.map(groupByAxisChoice)
output:
[
0: [ {age: 15, count: 242, role: "JW"}] // length 1
1: [ {age: 21, count: 995, role: "JW"} , {age: 21, count: 137, role: "SW"} ] // length 2
2: [ {age: 25, count: 924, role: "JW"}, {age: 25, count: 455, role: "SW"}, {age: 25, count: 32, role: "EW"} ]
]
I would like the nested arrays to be single objects, using their role as the key, and count as the value
expected output would look like this
[
{age :15, JW: 242},
{age: 21, JW:995, SW: 137},
{age: 25, JW: 924, SW: 445, EW: 32}
]
Edit: I have tried the following code
const result = groupByAxisChoice.reduce(
(obj, item) => Object.assign(obj, { [item.role]: item.count }),
{},
)
Which outputs: { undefined: undefined }
Figured it out...
const result = groupByAxisChoice.map(items =>
items.reduce((obj, item) => Object.assign(obj, { age: item.age, [item.role]: item.count }), {}),
)
This is what I ended up with, I know it's not optimized:
var arr = [
[ {age: 15, count: 242, role: "JW"}], // length 1
[ {age: 21, count: 995, role: "JW"} , {age: 21, count: 137, role: "SW"} ], // length 2
[ {age: 25, count: 924, role: "JW"}, {age: 25, count: 455, role: "SW"}, {age: 25, count: 32, role: "EW"} ]
];
var newArr = [];
arr.forEach(function(a) {
var ob = {age: a[0].age};
a.forEach(d => ob[d.role] = d.count);
newArr.push(ob);
});
I'll try to make it better (i don't know how to use underscore.js)...
another solutions
const b = a.map(item => {
return item.reduce((arr,curr) => {
return {
...arr,
['age']: curr['age'],
[curr['role']]: curr['count'],
}
}, {})
})
console.log(b)
If I have a JavaScript object such as:
var currencies= {
"EUR": 100,
"CHF": 15,
"GPB": 75,
"JPN": 116,
"EUR": 12,
"JPN": 15,
"USD": 55,
"CHF": 22,
"USD": 100,
};
Is there a way to sort them in this specific order?
var currencies= {
"EUR": 12,
"EUR": 100,
"USD": 55,
"USD": 100,
"GPB": 75,
"CHF": 15,
"CHF": 22,
"JPN": 15,
"JPN": 116,
};
By having an array with objects with a single key/value pair, you could take this pair for sorting by key and then by value.
var currencies= [{ EUR: 100 }, { CHF: 15 }, { GPB: 75 }, { JPN: 116 }, { EUR: 12 }, { JPN: 15 }, { USD: 55 }, { CHF: 22 }, { USD: 100 }],
order = { EUR: 1, USD: 2, GBP: 3, CHF: 4, JPN: 5 };
currencies.sort((a, b) => {
var aa = Object.entries(a)[0],
bb = Object.entries(b)[0];
return order[aa[0]] - order[bb[0]] || aa[1] - bb[1];
});
console.log(currencies);
.as-console-wrapper { max-height: 100% !important; top: 0; }