I have an array which contains many objects(all this data will come via ajax call, for example lets say there are only 3 records).
data : [{name : "a",id : "100"},{name : "b",id : "101"},{name : "c",id : "100"}];
Is there any way to loop through entire array and find objects with same id and concatenate their names and filter the array to be like this
data : [{name : "a,c",id : "100"},{name : "b",id:"101"}]
Thanks
You can use forEach() loop and check if id exists and concat name to that value.
var data = [{name : "a",id : "100"},{name : "b",id : "101"},{name : "c",id : "100"}];
var result = []
data.forEach(function(e) {
//Check if property with current object id exists in object provided as thisArg param and if it doesn't exists set its value to current object and push it to result array
if(!this[e.id]) this[e.id] = e, result.push(this[e.id])
// if it does exists then concat name of current object to name of existing one that had the same id
else this[e.id].name += ',' + e.name
}, Object.create(null))
console.log(result)
I suggest to use a hash table, which is used as a closure of the callback function. Then iterate over the objects and thest if the hash exists or not. If it exists, add the name to the name property of the object, otherwise create a new object with the actual data and push it to the result set.
Return the temporary array in Array#reduce.
var data = [{name : "a",id : "100"},{name : "b",id : "101"},{name : "c",id : "100"}];
data = data.reduce(function (hash) {
return function (r, a) {
if (hash[a.id]) {
hash[a.id].name += ',' + a.name;
} else {
hash[a.id] = { name: a.name, id: a.id };
r.push(hash[a.id]);
}
return r;
};
}(Object.create(null)), []);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Related
I have an object that looks like this:
var someUglyObject =
{
"1-1" : {foo1: "foo1-1Value", bar1: "bar1-1value"},
"1-2" : {foo2: "foo1-2Value", bar2: "bar1-2value"},
"2-1" : {foo2: "foo2-1Value", bar2: "bar2-1value"},
"2-2" : {foo2: "foo2-2Value", bar2: "bar2-2value"}
}
I need to simplify the nested object above and convert into a simpler object after some processing (concatenation) like below:
var myObj = {
"1": { propsTogether : "foo1-1Valuebar1-1valuefoo1-2Valuebar1-2value"},
"2": { propsTogether : "foo2-1Valuebar2-1valuefoo2-2Valuebar2-2value" }
}
My plan is to interate through the keys like this, but not sure how to group the props together based on the first char of the key , i.e. for a key with value of '2-1' - 2 should be the new key.
var myObj= {};
Object.keys(someUglyObject).forEach(function(key) {
}
You can use Object.keys and reudce
Here idea is
First get the keys out of object.
Sort them // Object don't have order
Now split key on - and use first element as key on op object.
Use object.values and join them in desired format and place it on respective key
var obj = {'1-1' : {foo1: "foo1-1Value", bar1: "bar1-1value"},'1-2' : {foo2: "foo1-2Value", bar2: "bar1-2value"},'2-1' : {foo2: "foo2-1Value", bar2: "bar2-1value"},'2-2' : {foo2: "foo2-2Value", bar2: "bar2-2value"}}
let op = Object.keys(obj).sort().reduce((op,inp)=>{
let key = inp.split('-',1)[0]
op[key] = op[key] || {props:''}
op[key].props = op[key].props + Object.values(obj[inp]).join('')
return op
},{})
console.log(op)
How can I get a value from a nested object, using an array of keys?
// my sample object
var obj = {
type : "Purchase",
category : "Apartment",
categoryOptions : {
apartment : {
floors : {
type : "number",
value : null,
placeholder : "Total Floors"
},
},
},
}
var keysArray = ["value", "floors", "apartment", "categoryOptions"]
I tried to use array.reduceRight to achieve this but could not make it work.
here is what I've tried :
var roadToValue = keysArray.reduceRight(
function(previousValue, currentValue){
return previousValue + "[" + currentValue + "]" ;
}
);
// above function results in a single string like
// "categoryOptions[apartment][floors][value]"
// which off-course can't be used as object key
// and obj[roadToValue] results in 'undefined'
is there any way so I can get the proper key to pass to obj here?
You definitely can use reduceRight for this. The problem is that you created a string, however you need to pass your object as initialValue and use the squared bracket notation:
var obj = {"type":"Purchase","category":"Apartment","categoryOptions":{"apartment":{"floors":{"type":"number","value":null,"placeholder":"Total Floors"}}}}
var keysArray = ["value", "floors", "apartment", "categoryOptions"]
var value = keysArray.reduceRight((r, e) => r[e] || r, obj)
console.log(value)
I have a following array, which contains dates.
var arrs= ["2016/10/4", "2016/10/4", "2016/10/7", "2016/10/7", "2016/10/7"];
I am reducing this array to get count of same dates, so I am using following code,
var maps = arrs.reduce(function(prev, cur) {
prev[cur] = (prev[cur] || 0) + 1;
return prev;
}, {});
console.log(maps);
Now, the count is available for each unique dates as follows in browser console,
Object {2016/10/4: 2, 2016/10/7: 3}
I want to make json object for this reduce object.
[{
date : 2016/10/4,
value : 2
},
{
date : 2016/10/7,
value : 3
}]
How to get it, I am not able to get length or make forEach to maps.
After generating the object use Object.keys and Array#map methods to generate the required array.
var arrs = ["2016/10/4", "2016/10/4", "2016/10/7", "2016/10/7", "2016/10/7"];
var maps = arrs.reduce(function(prev, cur) {
prev[cur] = (prev[cur] || 0) + 1;
return prev;
}, {});
maps = Object.keys(maps) // get all property name
// iterate and generate eleemnt
.map(function(k) {
// generate prefered structure of array eleement
return {
date: k,
value: maps[k]
};
});
console.log(maps);
How would I write a function that searches a JSON file to find the index where there exists an object containing a particular key-value pair? For example, the function would return 0 for the following JSON document if we were looking for value: '100.0' because key1 rests at index 0.
var object = {
key1 : {
name : 'xxxxxx',
value : '100.0'
},
key2 : {
name : 'yyyyyyy',
value : '200.0'
},
key3 : {
name : 'zzzzzz',
value : '500.0'
},
}
Here's a little fiddle for you:
http://jsfiddle.net/qskt9Lg9/
function findInJson(key1, value) { //pass it the desired matching key value pairs
var i = 0;
for (var key in object) { //this will iterate through key1 - key3
var current = object[key];
if (current[key1] == value) {
return i; //return the index
}
i++;//increment if no found
}
return -1;
}
and you would just call it like so:
findInJson("name", "xxxxxx")
This site: http://crunchify.com/how-to-iterate-through-jsonarray-in-javascript/ gives you a lot more info on how to parse JSON.
If it is guaranteed a key in your object will not be deleted and added later you can use:
function (object, key, value) {
var index = 0;
for (var oKey in object) {
if (object[oKey][key] === value) {
return index;
}
index++;
}
return -1;
}
But for..in statement iterates over an object in an arbitrary order. See: "Deleted, added or modified properties" section for detailed explanation.
It would be better to use an array and fit "keyN" into your {name, value} object if you want the order to be preserved.
If you are not interested in supporting IE8 and below, then you could use the Object.keys() method like :
function getIndex(val) {
for (i = 0; i < Object.keys(object).length; i++) {
if (object[Object.keys(object)[i]].value === val) {
return i;
}
};
return -1;
};
console.log( getIndex("100.0") ); // returns 0
console.log( getIndex("500.0") ); // returns 2
console.log( getIndex("800.0") ); // returns -1
See JSFIDDLE
I have combed the web to try and give myself some understanding as to what the following means as it pertains to the object below. What does "a" and "b" mean? Why is it significant?
students.sort(function(a, b){
return a.fn-b.ln
})
var students = [{
fn : "Stone",
ln : "Carpenter",
scores : [61,99,73,68,80,62,176,78]
},
{
fn : "Samson",
ln : "Sears",
scores : [68,193,91,190,95,65,171,75]
},
{
fn : "Quin",
ln : "Morton",
scores : [79,95,161,92,182,163,198,182]
},
{
fn : "Qunitessa",
ln : "Hardy",
scores : [99,65,75,69,77,67,86,78]
},
{
fn : "Ashley",
ln : "England",
scores : [147,70,81,64,148,71,70,63]
},
{
fn : "Thaddeus",
ln : "Hutchinson",
scores : [99,190,188,185,160,88,89,76]
},
{
fn : "Yeo",
ln : "Hayes",
scores : [88,64,199,165,198,76,74,81]
},
{
fn : "Rylee",
ln : "Larson",
scores : [71,126,63,71,168,173,175,88]
}
];
I understand that the anonymous function will return a value of -1,0,1, but what is the significance of the arguments a and b since I will not be passing any values (such as employees.sort(a.something, b.something)) when I call the function. With the above data I need to sort by clicking on one of the headers of my table -- which will involve sorting string and number values. Any ideas as to how to sort the nested values in the "scores" array? How would I go about sorting via the first/last name?
The sort method of an Array will take your sorting function and apply it when necessary to compare two elements and determining their sort order. a and b will be two elements of the Array you are sorting.
To sort your objects alphabetically by last name, you will need a sorting function like this one:
function lastNameCompare(a, b) {
var sortFieldA = a.ln.toLowerCase();
var sortFieldB = b.ln.toLowerCase();
return sortFieldA == sortFieldB ? 0 : (sortFieldA < sortFieldB ? -1 : 1);
}
Remove the .toLowerCase() if you want your sort to be case sensitive. To sort for something like "last name, first name" you would use the following lines instead:
var sortFieldA = (a.ln + ", " + a.fn).toLowerCase();
var sortFieldB = (b.ln + ", " + b.fn).toLowerCase();
To also sort the scores in your data you will need to perform a sort on every entry of your data set:
for (var i = 0; i < students.length; i++) {
var student = students[i];
student.scores.sort();
}
Note that you don't need an explicit sorting function in this case, since sort will use numeric sort order by default.
.sort takes a callback. It will then pick two elements from the array and pass them to the callback function. The callback function returns which element is greater. .sort rearranges the two elements in the array based on that information. It then takes two other elements and passes them into the callback. Rinse, repeat until the array is sorted.
a and b are simply the variables for "an element" and "another element". Call them whatever you like. There's no significance to the naming.