How can I get data iterate Json? - javascript

I need get data the my Json but I can't use 'key' because the 'key' is different each day.
I tried :
template: function(params) {
const objects = JSON.parse(JSON.stringify(params.data.masterdetail));
for (const obj of objects) {
const keys = Object.keys(obj);
const cont = 0;
keys.forEach(key => {
const valor = obj[key];
console.log('value ', valor[0]);
});
}
I first tried with 0 and then use cont, but with 0 console.log (value is undefined)....
If I use console.log ('value' , valor['name']) IT'S OK ! but I can't use keys and if I use valor[0] is undefined...........
Example Json
{
"headers": [
"headerName": "asdasd",
], //end headers
"datas": [
"idaam": "11",
"idorigen": "11",
"masterdetail": [{
"child1": {
"name": "I AM",
"age": "1"
},
"child2": {
"name": "YOU ARE",
"age": "2"
},
"child3": {
"name": "HE IS",
"age": "3"
},
}] //end masterdetail
]//end datas
}//end JSON
Edit :
I can't use 'keys' because today I receive "name", "typeval" etc. and tomorrow I can get 'surname','id' etc.
If you see in my first img you can see "4" bits of data.
1º obj[key]{
name = "adopt",
typeval= "",
etc
}
2º obj[key]{
"link" = "enlace",
"map" = "map"
etc
}
If I use this code : I get "name" OKEY but
I HAVE PROHIBITED use of value['name'] or value[typeval] because this Json always is dynamic.
var objects = params.data.masterdetail[0];
const keys = Object.keys(objects);
let value;
keys.forEach(key => {
value = objects[key];
console.log(value['name']);
console.log(value['typeval']);
});
I need for example :
var objects = params.data.masterdetail[0];
const keys = Object.keys(objects);
cont = 0 ;
keys.forEach(key => {
value = objects[key];
console.log(value[0]);
});
but value[0] is undefined and then when I arrive 2ºobj[key] link is index 0 but cont maybe is .... 4...
Sorry for my English...

To simply print the objects within the first entry in the masterdetail array, you can do the following:
var objects = params.datas.masterdetail[0];
const keys = Object.keys(objects);
keys.forEach(key => {
console.log('value ', objects[key]);
});
Based on a (suitably corrected - see my comments above) version of the JSON above, this would produce console output as follows:
value {name: "I AM", age: "1"}
value {name: "YOU ARE", age: "2"}
value {name: "HE IS", age: "3"}
Unfortunately it's not 100% clear from the question if this is the output you were looking for, but that's my best guess based on the code.
Your main mistakes were that
1) masterdetail is an array, and all the data is within the first element of that array, so to get the objects within it you need to select that element first. If the array can have multiple elements in real life then you'd need an outer loop around the code above to iterate through it.
2) If you're looping through the keys of an object, you don't need to also iterate through the properties a different way. You seemed to have two loops designed to do the same thing.

Related

javascript array push keeps repeating it self cant find out why

I cant figure out why this arrayUnd gets repeated key values. ive been on this for three weeks. I must be doing somehthing stupid. I know they are loops. but everything works except the push. it logs when the key repeats and stuff. but it somehow is adding it to it? very confusing.
Heres my Javascript
var array = [
{"size":["12","22"]},
{"color":["blue"]},
{"design":["flower-blue"]},
{"size":["12","22","44"]},
{"color":["red"]},
{"design":["flower-blue"]}
]
//output array
arrayUnd=[
{"color":["red"]}
]
//is array?
console.log( Array.isArray(array))
function pusher(obj){
arrayUnd.push(obj)
}
function isRepeat(key,value,obj){
// console.log(key[0])
for (let item=0; item < arrayUnd.length; item++ ){
if ( arrayUnd[item].hasOwnProperty(key)){
console.log("key: " + key)
console.log("yes")
console.log(arrayUnd)
}
else{
console.log("keyno: " + key)
console.log("no")
//pusher(obj)
if ( arrayUnd[item].hasOwnProperty(key) === false){
pusher(obj)
}
console.log(arrayUnd)
}
}
}
array.forEach((obj)=>{
var a= Object.keys(obj)
var b= Object.values(obj)
isRepeat(a,b,obj)
})
console.log(arrayUnd)
Your loop is checking all objects to see if they don't match. At least one of them won't match, so it will try to push that many times. You need to check all elements, and after checking them all for existence decide if you want to push or not.
Current logic is equivalent to: if anything in arrUnd doesn't match, push me each time I check.
some works here, because it checks if anything matches, and returns true or false, which you can then use to decide if you want to push or not (only once, after I've found if anything in the array matches, deciding using the final result).
Using some to check if any other element with same key exists. Push if nothing found.
var array = [{
"size": ["12", "22"]
},
{
"color": ["blue"]
},
{
"design": ["flower-blue"]
},
{
"size": ["12", "22", "44"]
},
{
"color": ["red"]
},
{
"design": ["flower-blue"]
}
]
//output array
arrayUnd = [{
"color": ["red"]
}]
//is array?
console.log(Array.isArray(array))
function pusher(obj) {
arrayUnd.push(obj)
}
function isRepeat(key, value, obj) {
if(!arrayUnd.some(x => x.hasOwnProperty(key[0])))
arrayUnd.push(obj)
}
array.forEach((obj) => {
var a = Object.keys(obj)
var b = Object.values(obj)
isRepeat(a, b, obj)
})
console.log(arrayUnd)
You are passing an array to isRepeat instead of the key and value of the object.
Object.keys() returns an array, even if the object only has one key.
When you check if ( arrayUnd[item].hasOwnProperty(key) === false), arrayUnd[item].hasOwnProperty(key) will always be false, so the object will always get pushed to your array.
You can fix this by accessing the first key and value of each object:
array.forEach((obj)=>{
var a= Object.keys(obj)
var b= Object.values(obj)
isRepeat(a[0],b[0],obj)
})
The reason your code keeps pushing object to arrayUnd it's because when it iterates through the array it checks for the array key if its present if not it pushes it to arrayUnd, now you have 2 problems first you are not actually checking for the array key to match you comparing object so you will always get false , and second is that each time you push to the array the length of your array grow and so the number of iterations increases
you can achieve this in two lines of code
var array = [
{"size":["12","22"]},
{"color":["blue"]},
{"design":["flower-blue"]},
{"size":["12","22","44"]},
{"color":["red"]},
{"design":["flower-blue"]}
]
//output array
arrayUnd=[
{"color":["red"]}
]
array.forEach(p=>Object.entries(p).forEach(p=>{
!arrayUnd.some(o=>o.hasOwnProperty(p[0])) ? arrayUnd.push({[p[0]]:p[1]}):null
}))
console.log(arrayUnd)
var inpAry = [
{ "size": ["12", "22"] },
{ "color": ["blue"] },
{ "design": ["flower-blue"] },
{ "size": ["12", "22", "44"] },
{ "color": ["red"] },
{ "design": ["flower-blue"] }
];
var opAry = [
{ "color": ["red"] }
];
inpAry.forEach(inpAryElem => {
var ipAryElemKeys = Object.keys(inpAryElem);
var ipAryElemVals = Object.values(inpAryElem);
ipAryElemKeys.forEach((ipAryElmKey,ipAryElemKyIdx) => {
var isKeyPresent = false;
opAry.forEach(opAryElem => {
if(opAryElem[ipAryElmKey]) {
isKeyPresent = true;
opAryElem[ipAryElmKey].push(...ipAryElemVals[ipAryElemKyIdx]);
}
});
if(!isKeyPresent) {
opAry.push({[ipAryElmKey]:ipAryElemVals[ipAryElemKyIdx]});
}
})
});
console.log(opAry);

remove and count duplicates from an groupedBy array in Javascript

I have an array which should be modified in a way that it removes and counts duplicate lamps for each room. Currently I have the following array:
I want to have them grouped by room. I use the lodash function for that:
groupByAndCount(lamps) {
const groupedArray = groupBy(lamps, function(n) {
return n.pivot.room;
});
return groupedArray;
},
This returns the array like this:
Basically each grouped Object looks the same like the objects in the first array. But now I want to use the function I wrote to count and remove the duplicates:
removeAndCountDuplicates(lamps) {
// map to keep track of element
// key : the properties of lamp (e.g name, fitting)
// value : obj
let map = new Map();
// loop through each object in Order.
lamps.forEach(data => {
// loop through each properties in data.
let currKey = JSON.stringify(data.name);
let currValue = map.get(currKey);
// if key exists, increment counter.
if (currValue) {
currValue.count += 1;
map.set(currKey, currValue);
} else {
// otherwise, set new key with in new object.
let newObj = {
id: data.id,
name: data.name,
fitting: data.fitting,
light_color_code: data.light_color_code,
dimmability: data.dimmability,
shape: data.shape,
price: data.price,
watt: data.watt,
lumen: data.lumen,
type: data.type,
article_number: data.article_number,
count: 1,
image: data.image
// room: data.pivot.room
};
map.set(currKey, newObj);
}
});
// Make an array from map.
const res = Array.from(map).map(e => e[1]);
return res;
},
The result should be an array like the first one. But should contain this:
1 Lamp for each room with the count of how many times it occurs
So the object should be like this:
id
name:
fitting:
light_color_code:
dimmability:
shape:
price:
watt:
lumen:
type:
article_number:
room:
count:
But I couldn't manage to get the functions work together so it returns this array. Can anyone help me in the right direction? Thanks in advance, any help is appreciated. It feels like i'm almost there.
Some sample data:
{
"id": 3,
"name": "Noxion Lucent LED Spot PAR16 GU10 4W 827 36D | Extra Warm Wit - Vervangt 50W",
"fitting": "GU10",
"light_color_code": "2700K - 827 - Zeer warm wit",
"dimmability": 0,
"shape": "Spot",
"price": 2.44,
"watt": 4,
"lumen": 370,
"type": "LED ",
"article_number": 234987,
"pivot": {
"order_id": 2,
"lamp_id": 3,
"room": "Garage"
},
"image": {
"id": 3,
"lamp_id": 3,
"name": "234987",
"path": "/storage/234987.jpg"
}
}
Since in the group by, you are creating an object with keys and arrays as it's values, you have to first iterate on the object (you can use Object.entries()) and then it's arrays.
Try passing the grouped object to the function below and you should get the array with correct counts.
Here's a sample to play with - https://stackblitz.com/edit/js-d2xcn3
NOTE: I have used pivot.lamp_id (and added it in the object as well) to use as the key for the map. You can choose to change it to some other unique property.
const removeDuplicates = (lamps) => {
let map = new Map();
Object.entries(lamps).forEach(([key, value])=> {
// loop through each object in Order.
lamps[key].forEach(data => {
// loop through each properties in data.
let currKey = JSON.stringify(data.pivot.lamp_id);
let currValue = map.get(currKey);
// if key exists, increment counter.
if (currValue) {
currValue.count += 1;
map.set(currKey, currValue);
} else {
// otherwise, set new key with in new object.
let newObj = {
lamp_id: data.pivot.lamp_id,
id: data.id,
name: data.name,
fitting: data.fitting,
light_color_code: data.light_color_code,
dimmability: data.dimmability,
shape: data.shape,
price: data.price,
watt: data.watt,
lumen: data.lumen,
type: data.type,
article_number: data.article_number,
count: 1,
image: data.image
// room: data.pivot.room
};
map.set(currKey, newObj);
}
});
})
// Make an array from map.
const res = Array.from(map).map(e => e[1]);
return res;
}

From an array of objects, extract properties into multiple arrays (one per property)?

I have a JSON array of objects in JS that look something like this:
"data": [
{"name": "abc", "location": "NY", "value": 1234, "potato": "tomato", "someOtherProp": "prop1"},
{"name": "def", "location": "CA", ... etc}
{etc ...},
]
I'm creating a UI for filtering down some of these fields and want to create an array for each attribute with all the given values in the data.
I know this is possible using something like this:
let result = objArray.map(a => a.name);
But using this strategy, I have to run map once for every property. Is there any way to only go through the array once but create a separate array for each? (Or is there a better way in general for creating filter options for a UI?)
To clarify, for the array above, I'd want an array for "names" (containing "abc" and "def"), an array for "locations" (containing NY, CA, etc.) an array for "potato"s and "someOtherProp".
I appreciate any help!
Thanks
Loop through the array with .reduce(). In each iteration, loop through the keys of the object using Object.keys(), adding any unique values to an array of the same name.
This solution eliminates duplicate entries and works with any amount of properties.
const data = [{name: "abc", location: "NY"},{name: "def", location: "CA"},{name: "xyz", location: "TX"},{name: "zyx", location: "TX"}];
const getFiltersFromData = (data) => {
return data.reduce((out,obj) => {
Object.keys(obj).forEach(k => {
if (out[k] === undefined) out[k] = [obj[k]]; //Array doesn't exist yet - instantiate it
else if (!out[k].includes(obj[k])) out[k].push(obj[k]); //Array exists and this value isn't in it - add the value to it
});
return out;
}, {});
};
const filters = getFiltersFromData(data);
console.log(filters.name);
console.log(filters.location);
.as-console-wrapper, .as-console { height: 100% !important; max-height: 100% !important; top: 0; }
You could create the separate arrays from names, locations and values and then use map on the data array to push each attribute value to the arrays. You can do that vs. running map multiple times for each property:
var names = [];
var locations = [];
var values = [];
data.map((elt) => {
names.push(elt.name);
locations.push(elt.location);
values.push(elt.value);
});
Try with Object.entries
You can get something like this:
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

how to get unique values from array of objects with addition of numbers

I'm working in wso2 carbon dashboard. My table is containing 2 fields (Name and Number). I Have duplicate name in the objects but with different number. I want unique name with addition of numbers.
[
{
"Name":"Abc",
"number":2
},
{
"Name":"bcd",
"number":3
},
{
"Name":"Abc",
"number":5
}
]
expected output
[
{
"name":"Abc",
"Number":7
},
{
"name":"bcd",
"Number":3
}
]
I'm using java script to achieve such task. please help me
Use Array#reduce method with a reference object.
var data = [{
"Name": "Abc",
"number": 2
}, {
"Name": "bcd",
"number": 3
}, {
"Name": "Abc",
"number": 5
}];
// object for index reference
var ref = {};
// iterate and generate the array
var res = data.reduce(function(arr, o) {
// check index already defined
if (!(o.Name in ref)) {
// if not defined then define index
ref[o.Name] = arr.length;
// and push the element
// you can also use
// arr.push({Name:o.Name, number:o.number});
arr.push(Object.assign({}, o));
} else {
// if index already defined update the number
arr[ref[o.Name]].number += o.number;
}
// return the array reference
return arr;
// set initial value as empty array
}, []);
console.log(res);

underscorejs pluck two dimensional array

First time using underscore and I am stuck and cannot find an example.
My data is:
[{
"store_name": "Store 1",
"franchisee_id": "id01",
"dish_menu": "Breakfast",
"dish_count": "17"
}, {
"store_name": "Store 1",
"franchisee_id": "id01",
"dish_menu": "Light Meals",
"dish_count": "7"
}, {
"store_name": "Store 1",
"franchisee_id": "id01",
"dish_menu": "Sandwiches",
"dish_count": "12"
}, {
"store_name": "Store 2",
"franchisee_id": "id02",
"dish_menu": "Breakfast",
"dish_count": "7"
},
............
]
I have managed (with some help from here) to pull the distinct store_name with the following chained command and then place it into a HTML statement I am building:
var stores = _.chain(json).pluck("store_name").sort().uniq(true).value();
var tempHTML = "";
stores.forEach(function (entry) {
tempHTML = tempHTML + '<option value="' + entry + '">' + entry + '</option>';
});
But I am trying to match the franchisee_id to the distinct store_name and essentially build my HTML like below:
stores.forEach(function (entry) {
tempHTML = tempHTML + '<option value="' + FRANCHISEE_ID + '">' + STORE_NAME + '</option>';
});
Is there a way to _.pluck a value for franchisee_id using the store_name value? There is a 1:1 relationship between these two fields so even getting the "first found" franchisee_id is fine. Thanks!
You could do something like this to get your id/name pairs in the desired order:
var map_id_to_name = function(m, o) {
m[o.franchisee_id] = o.store_name;
return m;
};
var arrayify = function(name, id) {
return [ name, id ];
};
var stores = _(data).chain()
.reduce(map_id_to_name, { })
.map(arrayify)
.sortBy(_.first)
.value();
Demo: http://jsfiddle.net/ambiguous/9xxS6/
That will give you an array of arrays in stores that you can spin through to build your <option>s; stores will look like this:
[
[ "Store 1", "id01" ],
[ "Store 2", "id02" ],
...
]
The store name will be in the first entry of the inner arrays and the franchise ID in the second. The whole thing will be sorted by store name. If you want a case insensitive sort then you can .sortBy(function(a) { return a[0].toLowerCase() }) instead.
The reduce(map_id_to_name, { }) collects the unique id/name pairs using an Object to automatically enforce uniqueness (the keys in an Object are unique after all). Then map(arrayify) converts the Object to an array-of-arrays so that you can sort things. You could use an array-of-objects instead, that would just be a small alteration to the map and sortBy calls.
A different approach, extracting the desired information from the objects and then filtering the resulting array to get unique objects:
var stores = _(data).chain()
// convert each object to {store_name: ..., franchisee_id: ...}
.map(function(m) {
return _.pick(m, "store_name", "franchisee_id");
})
//keep one of each
//can be shortened to .uniq(_.property('franchisee_id'))
.uniq(function(m) {
return m.franchisee_id;
})
//sort by name
.sortBy("store_name")
//and get the array
.value();
Your final array would look like
[
{store_name: "Store 1", franchisee_id: "id01"},
{store_name: "Store 2", franchisee_id: "id02"}
]
And a demo to play with http://jsfiddle.net/mr82s/
And with a little _.mixin magic, you could further condense it to
_.mixin({
properties: function() {
var args = _.toArray(arguments);
return function(obj) {
return _.pick(obj, args);
};
}
});
var stores = _(data).chain()
.map(_.properties("store_name", "franchisee_id"))
.uniq(_.property('franchisee_id'))
.sortBy("store_name")
.value()
http://jsfiddle.net/nikoshr/mr82s/1/

Categories

Resources