I have arrays of objects ob1 and ob2 and I want to check whether the total quantity total of each object is be equal with the sum of the qtys of the objects in the info array.
if total = sum(info.qty) for all objects then return an empty array otherwise return the objects with the invalid total fields.
My attempt so far:
function checktotal(ob1) {
var result = ob1.forEach(e => {
if (e.info.length > 0) {
var sum = e.info.reduce((a, {qty}) => a + qty, 0);
if (sum !== e.total) {
return "total qty not matches with info total qty,"+e
}
})
}
var ob1 = [
{id:1, total: 2, info:[{idx:1, qty:1},{idx: 2, qty: 2}] },
{id:2, total:1, info: [{idx:1, qty:1}] };
];
var ob2 = [
{id:1, total: 1, info:[{idx:1, qty:1}] },
{id:2, total:4, info: [{idx:1, qty:2},{idx: 2, qty: 2}] };
];
Expected Output:
checktotal(ob1); // should return [{id:1, total:2, info:[{idx:1, qty:1}, {idx:2, qty:2}]}]
checktotal(ob2); // should return []
You can filter the records by comparing total and getting total of info qty by making use of reduce(). Here is a working example
var ob1 =[
{id:1, total: 2, info:[{idx:1, qty:1},{idx: 2, qty: 2}] },
{id:2, total:1, info: [{idx:1, qty:1}]}
];
var result = ob1.filter(k=>k.total!=k.info.reduce((a, {qty})=>a+qty,0));
console.log(result);
I hope this will lead you towards right direction.
Working commented example:
// finds total sum of qtys in info array
function totalSum(infoArray) {
return infoArray.reduce((acc, info) => acc + info.qty, 0);
}
// returns items with incorrect totals
function checkTotal(itemArray) {
return itemArray.filter(item => item.total !== totalSum(item.info));
}
let ob1 = [
{id:1, total:2, info:[{idx:1, qty:1}, {idx:2, qty:2}]}, // incorrect total
{id:2, total:1, info:[{idx:1, qty:1}]}, // correct total
];
let ob2 = [
{id:1, total:1, info:[{idx:1, qty:1}]}, // correct total
{id:2, total:4, info:[{idx:1, qty:2}, {idx: 2, qty: 2}]}, // correct total
];
console.log(checkTotal(ob1)); // returns 1st item
console.log(checkTotal(ob2)); // returns empty array
I think you are looking for a function that returns the subset of objects from an input array of objects for which the total amount in total does not equal the sum of the amounts in qty in the objects inside info.
You can use filter() to get the array of mismatching objects, and the condition to check the sum makes use of reduce(). Below is a working example.
Please note that unlike what you requested, the call on the first array of objects returns an array that contains the culprit object, instead of just the object itself.
function checkTotal(data) {
return data.filter(({ total, info }) => (
total !== info.reduce((acc, { qty }) => (acc + qty), 0)
));
}
var ob1 = [
{ id: 1, total: 2, info: [{ idx: 1, qty: 1 }, { idx: 2, qty: 2 }] },
{ id: 2, total: 1, info: [{ idx: 1, qty: 1 }] }
];
var ob2 = [
{ id: 1, total: 1, info: [{ idx: 1, qty: 1 }] },
{ id: 2, total: 4, info: [{ idx: 1, qty: 2 }, { idx: 2, qty: 2}] }
];
console.log('ob1', checkTotal(ob1));
console.log('ob2', checkTotal(ob2));
Related
I have a groupedBy subscription lodash array, and I want to sum the quantity property and return the value.
Example
{
sub_1MT4LuP6DArCazGmEdJd: [
{
id: 'prod_HleWjM6culM',
quantity: 1,
},
{
id: 'prod_HleWjM6culM',
quantity: 3,
}
]
}
The output should be:
{
sub_1MT4LuP6DArCazGmEdJd: [
{
totalQuantity: 4,
},
]
}
Which is the best way to do this sum of values in a lodash grouped array?
You can use _.sumBy.
let o = {
sub_1MT4LuP6DArCazGmEdJd: [
{
id: 'prod_HleWjM6culM',
quantity: 1,
},
{
id: 'prod_HleWjM6culM',
quantity: 3,
}
]
};
o.sub_1MT4LuP6DArCazGmEdJd = [{totalQuantity:
_.sumBy(o.sub_1MT4LuP6DArCazGmEdJd, 'quantity')}];
console.log(o);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
const dataAll = [ {id: 1, slp: { total: '3' }},{id: 2, slp: { total: '6' }},{id: 3, slp: { total: '5' }} ]
const res = dataAll.map((singleData) => singleData.data.slp.total);
const theres = JSON.stringify(res);
console.log(theres);
How can I add up all the total numbers from the array above?
so I can get the total of 3 + 6 + 5 = 14
and to get a number of the total number of an array in .length total of 3 example
You can easily add them using reduce and take the length as dataAll.length
const dataAll = [
{ id: 1, slp: { total: "3" } },
{ id: 2, slp: { total: "6" } },
{ id: 3, slp: { total: "5" } },
];
const total = dataAll.reduce((acc, curr) => +curr.slp.total + acc, 0);
const length = dataAll.length;
console.log(total, length);
try this:
const dataAll = [{ id: 1, slp: { total: '3' } }, { id: 2, slp: { total: '6' } }, { id: 3, slp: { total: '5' } }]
let total = 0
dataAll.map((singleData)=>{
total += parseInt(singleData.slp.total)
})
//Use whatever hook you need here to store the total value
setTotalHook(total, dataAll.length)
console.log(total)
You can use reduce to sum up values in an array.
const dataAll = [ {id: 1, slp: { total: '3' }},{id: 2, slp: { total: '6' }},{id: 3, slp: { total: '5' }} ]
const res = dataAll.reduce((partial_sum, a) => partial_sum + parseInt(a.slp.total), 0);
const theres = JSON.stringify(res);
console.log(theres);
For length just check the length property of the array.
To sum up the totals you can use reduce to iterate over the array of objects and add the value of total to the accumulator (initially set to zero) on each iteration. Note: you need to coerce that value to a number.
const data = [ {id: 1, slp: { total: '3' }},{id: 2, slp: { total: '6' }},{id: 3, slp: { total: '5' }} ];
const sum = data.reduce((acc, c) => {
// Coerce the string value to a number
// and add it to the accumulator
return acc + Number(c.slp.total);
}, 0);
console.log(`Length: ${data.length}`);
console.log(`Sum: ${sum}`);
You should be able to use reduce.
const dataAll = [ {id: 1, slp: { total: '3' }},{id: 2, slp: { total: '6' }},{id: 3, slp: { total: '5' }} ]
const sum = dataAll.reduce(((total, b) => total + parseInt(b.slp.total, 10)), 0);
const totalElements = dataAll.length;
console.log(sum, totalElements)
I just started learning JavaScript, I have this type of array, how I can turn this array of objects into key-value pairs like below, Any source and reference is acceptable.
Sample Array:
[
{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},
{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}
]
Expected Result:
{
"6d7e75e6-c58b-11e7-95-ac162d77eceb":1,
"6d2e75e6-c58b-11e7-95-ac162d77eceb":1
}
Using Array.prototype.Reduce:
const arr = [{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}];
const result = arr.reduce((acc, { Id, qty }) => ({ ...acc, [Id]: qty }), {});
console.log(result);
Another approach, a little more beginner friendly.
const arr = [
{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},
{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}
];
const newObject = {}; // empty object
// loop over each element of the array
arr.forEach(element => {
// the key is the element identifier (Id) and the value is the element quantity (qty)
newObject[element.Id] = element.qty;
});
You can use a loop and add the item.Id as the key and the item.qty as the value in an empty object.
let arr = [{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}]
let obj = {}
arr.forEach(item => {
obj[item.Id] = item.qty
})
console.log(obj)
You can easily achieve this result using forEach in a single line of code.
const arr = [
{ Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 },
{ Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 },
];
const result = {};
arr.forEach(({ Id, qty }) => (result[Id] = qty));
console.log(result);
You can achieve the desired result with below code
//input array
const arrList = [
{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},
{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}
]
function findArray(arr) {
//define a new array to store Id's
let newArray = [];
//iterate through array items
arr.forEach(item => {
newArray.push(item.Id);
});
return newArray;
}
//call findArray function to get desired output
console.log(findArray(arrList));
Using Object.fromEntries()
const
array = [{ Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 }, { Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 }],
object = Object.fromEntries(array.map(({ Id, qty }) => [Id, qty]));
console.log(object);
or, for some fragile novelty...
const
array = [{ Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 }, { Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 }],
object = Object.fromEntries(array.map(Object.values));
console.log(object);
I have two arrays:
var array1 = [{id: 1, time: 100}, {id: 2, time: 200}, {id: 3, time: 300}];
var array2 = [{id: 1, time: 100}, {id: 3, time: 300}];
And I would like for array2 to be changed to
var array2 = [{id: 1, time: 100}, null, {id: 3, time: 300}];
The question is how can I compare the two arrays and look at their time and then insert null in the missing locations for each array.
Any help is appreciated!
const arr1 = [{id: 1, time: 100}, {id: 2, time: 200}, {id: 3, time: 300}];
const arr2 = [{id: 1, time: 100}, {id: 3, time: 300}, {id: 3, time: 400}];
const uniqueTimes = [...arr1, ...arr2]
.filter((e, i, a) => a.findIndex(x => x.time === e.time) === i)
const res1 = uniqueTimes.map(e =>
arr1.find(x => x.time === e.time) ?? null
)
const res2 = uniqueTimes.map(e =>
arr2.find(x => x.time === e.time) ?? null
)
console.log(res1)
console.log(res2)
Your example is a little misleading. Your description of the prompt says entries can be missing in both arrays, right? My example has 200 missing in array2, and 400 missing in array1
var array1 = [{ id: 1, time: 100 }, { id: 2, time: 200 }, { id: 3, time: 300 }];
var array2 = [{ id: 1, time: 100 }, { id: 3, time: 300 }, { id: 1, time: 400 }];
// get all possible times, sort them
const allSortedTimes = array1.map(({ time }) => time).concat(array2.map(({ time }) => time)).sort((a, b) => a - b)
// only use uniq times
const allUniqTimes = [...new Set(allSortedTimes)]
// now that we have all the possible times,
// we go over each array and check to see if that time exists
const insertedArray1 = allUniqTimes.map((uniqTime) => {
return array1.find(({ time }) => time === uniqTime) ?? null
})
const insertedArray2 = allUniqTimes.map((uniqTime) => {
return array2.find(({time}) => time === uniqTime) ?? null
})
console.log(insertedArray1)
console.log(insertedArray2)
Here's one way to do it.
var array1 = [{
id: 1,
time: 100
}, {
id: 2,
time: 200
}, {
id: 3,
time: 300
}];
var array2 = [{
id: 1,
time: 100
}, {
id: 3,
time: 300
}];
const fixArray = (a, maxTime) => {
let inc = 100,
start = inc,
tmp = [];
// first make sure we have it in order
//a = a.sort((a, b) => (a.time < b.time) ? -1 : 1)
while (start < maxTime) {
let t = a.filter(el => el.time === start)
if (t.length === 0) tmp.push(null);
else tmp.push(t[0])
start += inc;
}
return tmp
}
array2 = fixArray(array2, 1000);
console.log(array2)
const getKey=(id,time)=>id+"_"+time //Provides unique key based on object values
var array1 = [{id: 1, time: 100}, {id: 2, time: 200}, {id: 3, time: 300}];
var array2 = [{id: 0, time: 5},{id: 1, time: 100},{id: 11, time: 250}, {id: 3, time: 300},{id: 5, time: 500}];
let keysOfArray1=[]//array1 unique keys
let keysOfArray2=[]//array2 unique keys
array1.map(item=>{
keysOfArray1.push(getKey(item.id,item.time)); // collects array1 unique keys
return item
}).concat(array2.map(item=>{//concat array2 values with array1
keysOfArray2.push(getKey(item.id,item.time)) // collects array2 unique keys
return item
})).sort((a,b)=>a.time-b.time || a.id-b.id).reduce((prev,current)=>{ //Sort by time & then Id
let keyName=getKey(current.id,current.time)
if(!prev.includes(keyName)){// To consider all objects only once
array1[prev.length]=keysOfArray1.includes(keyName)?current:null
array2[prev.length]=keysOfArray2.includes(keyName)?current:null
prev.push(keyName)
}
return prev
},[])
console.log(array1);
console.log(array2);
I am wondering if there is a way to dynamically add objects to an array of objects based on a value? For example, I have an array of objects:
[
{category:A, num:5},
{category:B, num:2}
]
I want to create another array of objects where objects would be the same, but repeated based on the value of num (so 5 times for category A and 2 times for category B) :
[
{category:A, num:5, repeated:1},
{category:A, num:5, repeated:2},
{category:A, num:5, repeated:3},
{category:A, num:5, repeated:4},
{category:A, num:5, repeated:5},
{category:B, num:2, repeated:1},
{category:B, num:2, repeated:2}
]
I have tried map, forEach, for loop, but nothing worked.
I am quite new to javascript, how some one could help!
You can do this using a combination of flatMap and map:
var input = [
{category:"A", num:5},
{category:"B", num:2}
] ;
var result = input.flatMap(e => [...new Array(e.num)].map( (x,i) => ({
category:e.category,
num: e.num,
repeated: i+1
})));
console.log(result);
You could do it using flatMap -
const repeat = ({ num = 0, ...t }) =>
num === 0
? []
: [ ...repeat({ ...t, num: num - 1 }), { ...t, num, repeated: num } ]
const input =
[ { category: "A", num: 5}, { category: "B", num: 2 } ]
const output =
input.flatMap(repeat)
console.log(output)
Output -
[
{ category: "A", num: 1, repeated: 1 },
{ category: "A", num: 2, repeated: 2 },
{ category: "A", num: 3, repeated: 3 },
{ category: "A", num: 4, repeated: 4 },
{ category: "A", num: 5, repeated: 5 },
{ category: "B", num: 1, repeated: 1 },
{ category: "B", num: 2, repeated: 2 }
]