Reduce JSON with JS - javascript

I am trying to reduce a JSON array. Inside the array are other object, I am trying to turn the attributes into their own array.
Reduce Function:
// parsed.freight.items is path
var resultsReduce = parsed.freight.items.reduce(function(prevVal, currVal){
return prevVal += currVal.item
},[])
console.log(resultsReduce);
// two items from the array
// 7205 00000
console.log(Array.isArray(resultsReduce));
// false
The reduce function is kind of working. It gets both item from the items array. However I am having a couple problems.
1) The reduce is not passing back an array. See isArray test
2) I am trying to make a function so I can loop through all of the attributes in the array the qty, units, weight, paint_eligable. I cannot pass a variable to the currVal.variable here
Attempting:
var itemAttribute = 'item';
var resultsReduce = parsed.freight.items.reduce(function(prevVal, currVal){
// pass param here so I can loop through
// what I actually want to do it create a function and
// loop through array of attributes
return prevVal += currVal.itemAttribute
},[])
JSON:
var request = {
"operation":"rate_request",
"assembled":true,
"terms":true,
"subtotal":15000.00,
"shipping_total":300.00,
"taxtotal":20.00,
"allocated_credit":20,
"accessorials":
{
"lift_gate_required":true,
"residential_delivery":true,
"custbodylimited_access":false
},
"freight":
{
"items":
// array to reduce
[{
"item":"7205",
"qty":10,
"units":10,
"weight":"19.0000",
"paint_eligible":false
},
{ "item":"1111",
"qty":10,
"units":10,
"weight":"19.0000",
"paint_eligible":false
}],
"total_items_count":10,
"total_weight":190.0},
"from_data":
{
"city":"Raleigh",
"country":"US",
"zip":"27604"},
"to_data":
{
"city":"Chicago",
"country":"US",
"zip":"60605"
}
}
Thanks in advance

You may need Array#map for getting an array of items
var resultsReduce = parsed.freight.items.reduce(function (array, object) {
return array.concat(object.item);
}, []);
The same with a given key, with bracket notation as property accessor
object.property
object["property"]
var key = 'item',
resultsReduce = parsed.freight.items.reduce(function (array, object) {
return array.concat(object[key]);
}, []);

Related

Find Unique value from an array based on the array's string value (Javascript)

so I want to find unique values from an array.
so for example I have this array:
const mainArr = ['shape-10983', 'size-2364', 'size-7800', 'size-4602', 'shape-11073', 'size-15027', 'size-15030', 'size-15033', 'height-3399', 'height-5884']
so I want to find the first matching value for each unique item.
for example, in the array, I have two strings with the shape prefix, six items with the size prefix, and two items with the height prefix.
so I want to output to be something like
const requiredVal = ["shape-10983", "size-2364", "height-3399"]
I want only the first value from any set of different values.
the simplest solution will be to iterate on the list and storing what you got in a dictionary
function removeSimilars(input) {
let values = {};
for (let value of input) {//iterate on the array
let key = value.splitOnLast('-')[0];//get the prefix
if (!(key in values))//if we haven't encounter the prefix yet
values[key] = value;//store that the first encounter with the prefix is with 'value'
}
return Object.values(values);//return all the values of the map 'values'
}
a shorter version will be this:
function removeSimilars(input) {
let values = {};
for (let value of input)
values[value.splitOnLast('-')[0]] ??= value;
return Object.values(values);
}
You could split the string and get the type and use it aks key for an object along with the original string as value. At result take only the values from the object.
const
data = ['shape-10983', 'size-2364', 'size-7800', 'size-4602', 'shape-11073', 'size-15027', 'size-15030', 'size-15033', 'height-3399', 'height-5884'],
result = Object.values(data.reduce((r, s) => {
const [type] = s.split('-', 1);
r[type] ??= s;
return r;
}, {}));
console.log(result);
If, as you mentioned in the comments, you have the list of prefixes already available, then all you have to do is iterate over those, to find each first element that starts with that prefix in your full list of possible values:
const prefixes = ['shape', 'size', 'height'];
const list = ['shape-10983', 'size-2364', 'size-7800', 'size-4602', 'shape-11073', 'size-15027', 'size-15030', 'size-15033', 'height-3399', 'height-5884']
function reduceTheOptions(list = [], prefixes = [], uniques = []) {
prefixes.forEach(prefix =>
uniques.push(
list.find(e => e.startsWith(prefix))
)
);
return uniques;
}
console.log(reduceTheOptions(list, prefixes));
Try this:
function getRandomSet(arr, ...prefix)
{
// the final values are load into the array result variable
result = [];
const randomItem = (array) => array[Math.floor(Math.random() * array.length)];
prefix.forEach((pre) => {
result.push(randomItem(arr.filter((par) => String(par).startsWith(pre))));
});
return result;
}
const mainArr = ['shape-10983', 'size-2364', 'size-7800', 'size-4602', 'shape-11073', 'size-15027', 'size-15030', 'size-15033', 'height-3399', 'height-5884'];
console.log("Random values: ", getRandomSet(mainArr, "shape", "size", "height"));
I modified the #ofek 's answer a bit. cuz for some reason the ??= is not working in react project.
function removeSimilars(input) {
let values = {};
for (let value of input)
if (!values[value.split("-")[0]]) {
values[value.split("-")[0]] = value;
}
return Object.values(values);
}
create a new array and loop over the first array and check the existing of element before in each iteration if not push it to the new array

How to add multiple values to existing keys for an array of objects?

I am trying to use reduce() for getting economy rate for a particular wicket.
Example data:
var data = [
{wicket:0, econ:20 },
{wicket:1, econ:10 },
{wicket:3, econ:45 },
{wicket:0, econ:15 },
{wicket:1, econ:32 }
]
I want reduce() method to return an array of objects which will look like this:
0: 20, 15
1: 10, 32
3: 45
What I am trying to do is initialize accumulator with object but in reduce() method I am not able to figure out how can I get the required array of objects with key value as wicketand values as economy.
My code:
const Economy = data.reduce( (a, {econ, wicket}) => {
a[wicket].push(econ);
},{})
I get undefined behaviour with above code.
If your data was meant to be an Array and not an Object (which it isn't right now, at least not a valid one) :
let data = [
{wicket:0, econ:20 },
{wicket:1, econ:10 },
{wicket:3, econ:45 },
{wicket:0, econ:15 },
{wicket:1, econ:32 }
];
let result = data.reduce((acc, curr) => {
if(acc[curr.wicket]) acc[curr.wicket].push(curr.econ);
else acc[curr.wicket] = [curr.econ];
return acc;
},{});
console.log(result);
You can use group the array using reduce like:
var data = [{"wicket":0,"econ":20},{"wicket":1,"econ":10},{"wicket":3,"econ":45},{"wicket":0,"econ":15},{"wicket":1,"econ":32}];
var result = data.reduce((c, v) => {
c[v.wicket] = c[v.wicket] || []; //Initiate the property as empty array of it does not exist
c[v.wicket].push(v.econ);
return c;
}, {});
console.log(result);
|| is an OR operator.
This means if c[v.wicket] exist, it will assign it to c[v.wicket] again. If it does not, assign an empty array []
c[v.wicket] = c[v.wicket] || [];

Copy array element modify and add again

Original array is newData. I wanted add one more array element to newData and added array Element should have Rank 1.
Issue is Rank is getting updated to 1 for both the records. Rank should be 1 for second record and 1st record should be null
Please tell me what i'm doing wrong here.
let newData = [{
"key1": {
"cc":'IND'
},
"key2": {
"rank": null
}
}];
let setData = newData.concat(newData.slice());
setData.forEach(data => {
data.key2.rank =+ 1;
});
You can try following
let newData = [{"key1": {"cc":'IND' }, "key2": {"rank": null}}];
// Concatenate arrays use spread operator and can use map rather than slice
let setData = [...newData, ...newData.map(data => {
/* Objects are passed by reference, you need to break the reference
* to create the clone of the object. */
data = JSON.parse(JSON.stringify(data));
data.key2.rank =+ 1;
return data;
})];
console.log(setData);
setData.forEach(data => {
data.key2.rank += 1;
});
Try to flip your operator from =+ to += instead

concatenate 2 object arrays to one

I have an object array containing one property call name like this
var nameArr = [
{
"name":"john"
},
{
"name":"carl"
},
{
"name":"peter"
}
]
I have a another array called ageArr and it only contain property called age
var ageArr = [
{
"age":"22"
},
{
"age":"21"
},
{
"age":"32"
}
]
i want to concat these array and end result should result like this
var result = [
{
"age":"22",
"name":"john"
},
{
"age":"21",
"name":"carl"
},
{
"age":"32",
"name":"peter"
}
]
note that length of the both arrays always equal and dynamic. Is there any way i can do this without looping these array inside one another. Thank you.
You can use Object.assign() and map() and return new array.
var nameArr = [{"name":"john"},{"name":"carl"},{"name":"peter"}]
var ageArr = [{"age":"22"},{"age":"21"},{"age":"32"}]
var result = nameArr.map(function(e, i) {
return Object.assign({}, e, ageArr[i])
})
console.log(result)
Single forEach() function is enough.
var nameArr=[{name:"john"},{name:"carl"},{name:"peter"}],
ageArr=[{age:"22"},{age:"21"},{age:"32"}];
nameArr.forEach((v,i) => v.age = ageArr[i].age)
console.log(nameArr);
You can use the following code snippet.
var result = nameArr.map(function( obj, index ) {
var res = ageArr[index];
res.name = obj.name;
return res;
});
In the map, you can easily use
jQuery.extend()
to create a merge of two same index object.

Querying Array of objects using javascript - Helper functions

if you are looking for Get/Delete/Sum/IsExist functions for an array of objects using javascript, I have posted this question and answer for such functions
Remove Object from an Array using JavaScript
Is Exist for an Object from an Array using JavaScript
Select Object from an Array using JavaScript
Sum Object values in an Array using JavaScript
How do I check if an array includes an object in JavaScript?
How do I remove a particular element from an array in JavaScript?
Find object by id in an array of JavaScript objects
summing numbers stored in an array in JavaScript, sum values of a javascript array?, Loop through array and return sum of all values
Btw, your question doesn't have much to do with JSON, and naught with jQuery.
Just use underscore.
Remove from a simple array:
var newList = _.without(list, 'hello', 'world'); // Remove any instance of 'hello' and 'world'
Remove from an array of objects:
var toRemove = _.where(list, {title: 'hello', subtitle: 'world'});
var newList = _.difference(list, toRemove);
Exists in array:
var exists = _.contains(list, value);
Get item from array:
var item = _.find(list, function(i){ i === value }); // For simple types
var item = _.findWhere(list, {title: 'hello', subtitle: 'world'}); // For complex types
Sum items:
var sum = _.reduce(list, function(start, num){ return start + num; }, 0);
And A LOT more.
4 Javascript Helpers
Remove Object from an Array using JavaScript
Is Exist for an Object from an Array using JavaScript
Select Object from an Array using JavaScript
Sum Object values in an Array using JavaScript
var JShelpers = {
removeItemFromArray: function (myObjects, prop, valu) {
return myObjects.filter(function (item) {
return item[prop] !== valu;
});
},
isExistInArray: function (myObjects, prop, valu) {
var i = myObjects.length;
while (i--) {
if (myObjects[i][prop] == valu) {
return true;
}
}
return false;
},
getItemFromArray: function (myObjects, prop, valu) {
var i = myObjects.length;
while (i--) {
if (myObjects[i][prop] == valu) {
return myObjects[i];
}
}
return "";
},
sumItemInArray: function (myObjects, prop) {
var summation = 0;
myObjects.forEach(function (item) {
summation += parseFloat(item[prop]);
});
return summation;
}
}
Example:
Say you have an array of Employees in a Json Format like this
var employeesArray = [{"Id":1,"Name":"tom","Age":15},{"Id":2,"Name":"Harry","Age":17}];
And you want to retrieve employee by his Age not only ID (as common) ,
you can simply call
JShelpers.getItemFromArray(employeesArray,"Age",15)

Categories