getting .text() of children elements from jQuery() - javascript

I'm having trouble to get the proper formatted texts of each child elements, either as an Array or in as text.
I had tried
var name= jQuery(".childOne").text();
var number = jQuery(".childTwo").text();
but it joins all the name/number text in name and number.
HTML is:
<span class="parent"><span class="childOne">David</span><span class="childTwo">541</span></span>
<span class="parent"><span class="childOne">Gruce</span><span class="childTwo">162</span></span>
<span class="parent"><span class="childOne">Proman</span><span class="childTwo">743</span></span>
and I need to generate output in multi-dim-array so that each child-element's-text can be figured out properly.
Preferred output can be in array or in any form.
Array
(
0 = > array (
0 => "David",
1 => "541"
),
1 = > array (
0 => "Gruce",
1 => "162"
),
2 = > array (
0 => "Proman",
1 => "743"
)
)

try this:
var data = [];
$('span.parent').each(function() {
var $this = $(this);
data.push({
'name' : $this.find('span.childOne').text(),
'number' : $this.find('span.childTwo').text()
});
});
BTW: jQuery uses the Sizzle selctor engine. You should define the element type before the class, like span.parent. This is much more faster.

If this is a fixed structure, you can do:
var data = [];
$('.parent').each(function() {
data.push({
'name': $(this).children('.childOne').text(),
'number': $(this).children('.childTwo').text()
});
});

I have made a working example
var array= [];
$('.parent').each(function(index) {
array.push({
'name': $(this).children('.childOne').text(),
'number': $(this).children('.childTwo').text()
});
});
alert(array[0].name);

$('.parent').each(function(index) {
alert($(this).find('.childOne').text());
alert($(this).find('.childTwo').text());
});
After you can put them into an array

Related

Dynamically create array of objects, from array of objects, sorted by an object property

I'm trying to match and group objects, based on a property on each object, and put them in their own array that I can use to sort later for some selection criteria. The sort method isn't an option for me, because I need to sort for 4 different values of the property.
How can I dynamically create separate arrays for the objects who have a matching property?
For example, I can do this if I know that the form.RatingNumber will be 1, 2, 3, or 4:
var ratingNumOne = [],
ratingNumTwo,
ratingNumThree,
ratingNumFour;
forms.forEach(function(form) {
if (form.RatingNumber === 1){
ratingNumOne.push(form);
} else if (form.RatingNumber === 2){
ratingNumTwo.push(form)
} //and so on...
});
The problem is that the form.RatingNumber property could be any number, so hard-coding 1,2,3,4 will not work.
How can I group the forms dynamically, by each RatingNumber?
try to use reduce function, something like this:
forms.reduce((result, form) => {
result[form.RatingNumber] = result[form.RatingNumber] || []
result[form.RatingNumber].push(form)
}
,{})
the result would be object, with each of the keys is the rating number and the values is the forms with this rating number.
that would be dynamic for any count of rating number
You could use an object and take form.RatingNumber as key.
If you have zero based values without gaps, you could use an array instead of an object.
var ratingNumOne = [],
ratingNumTwo = [],
ratingNumThree = [],
ratingNumFour = [],
ratings = { 1: ratingNumOne, 2: ratingNumTwo, 3: ratingNumThree, 4: ratingNumFour };
// usage
ratings[form.RatingNumber].push(form);
try this its a work arround:
forms.forEach(form => {
if (!window['ratingNumber' + form.RatingNumber]) window['ratingNumber' + form.RatingNumber] = [];
window['ratingNumber' + form.RatingNumber].push(form);
});
this will create the variables automaticly. In the end it will look like this:
ratingNumber1 = [form, form, form];
ratingNumber2 = [form, form];
ratingNumber100 = [form];
but to notice ratingNumber3 (for example) could also be undefined.
Just to have it said, your solution makes no sense but this version works at least.
It does not matter what numbers you are getting with RatingNumber, just use it as index. The result will be an object with the RatingNumber as indexes and an array of object that have that RatingNumber as value.
//example input
var forms = [{RatingNumber:5 }, {RatingNumber:6}, {RatingNumber:78}, {RatingNumber:6}];
var results = {};
$.each(forms, function(i, form){
if(!results[form.RatingNumber])
results[form.RatingNumber]=[];
results[form.RatingNumber].push(form);
});
console.log(results);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
HIH
// Example input data
let forms = [{RatingNumber: 1}, {RatingNumber: 4}, {RatingNumber: 2}, {RatingNumber: 1}],
result = [];
forms.forEach(form => {
result[form.RatingNumber]
? result[form.RatingNumber].push(form)
: result[form.RatingNumber] = [form];
});
// Now `result` have all information. Next can do something else..
let getResult = index => {
let res = result[index] || [];
// Write your code here. For example VVVVV
console.log(`Rating ${index}: ${res.length} count`)
console.log(res)
}
getResult(1)
getResult(2)
getResult(3)
getResult(4)
Try to create an object with the "RatingNumber" as property:
rating = {};
forms.forEach(function(form) {
if( !rating[form.RatingNumber] ){
rating[form.RatingNumber] = []
}
rating[form.RatingNumber].push( form )
})

Multidimensional array in jquery

My Jquery code
var attrid = [];
var attrvalue = [];
$.each($(".attname1"), function(index){
if($('.getval'+index+'').val() != undefined){
attrid.push($('.getval'+index+'').attr("id"));
attrvalue.push($('.getval'+index+'').val());
}
});
//outcome data
["5931", "5950", "5951", "5952"] //id
["cas", "bsd", "Canvas", "Grey"] //name
The result format that I actually want:
$ary = array (
[0] => array(
Id => 5931,
value=> cas,
),
[1] => array(
Id => 5950,
value=> bsd,
),
[2] => array(
Id => 5951,
value=> Canvas,
),
[3] => array(
Id => 5952,
value=> Grey,
)
);
Question:
Above code are using Jquery to loop the data and store into array, I'm trying to create loop to create the result format the I want, but I failed to do that,anyone can provide me some sample code or idea which is can using Jquery to create the results format that I provided.Thank you.
Make one array and push objects onto it:
var ary = [];
$('.attname1').each(function(index) {
var getval = $('.getval' + index);
if (getval.val()) {
ary.push({
id: getval.attr('id'),
value: getval.val()
});
}
});

Create an array of Objects from JSON

I have a JSON file like below:
[
{"fields":{category_class":"CAT2",category_name":"A"},"pk":1 },
{"fields":{category_class":"CAT1",category_name":"B"},"pk":2 },
{"fields":{category_class":"CAT1",category_name":"C"},"pk":3 },
{"fields":{category_class":"CAT2",category_name":"D"},"pk":4 },
{"fields":{category_class":"CAT3",category_name":"E"},"pk":5 },
{"fields":{category_class":"CAT1",category_name":"E"},"pk":6 },
]
I want to create an array of objects from the above JSON which will have two properties. i) CategoryClass ii) CategoryNameList. For example:
this.CategoryClass = "CAT1"
this.CategoryNameList = ['B','C','E']
Basically i want to select all categories name whose category class is CAT1 and so forth for other categories class. I tried this:
var category = function(categoryClass, categoryNameList){
this.categoryClass = categoryClass;
this.categoryList = categoryNameList;
}
var categories = [];
categories.push(new category('CAT1',['B','C','E'])
Need help.
You can use a simple filter on the array. You have a few double quotes that will cause an error in you code. But to filter only with CAT1 you can use the filter method
var cat1 = arr.filter( value => value.fields.category_class === "CAT1");
I would suggest this ES6 function, which creates an object keyed by category classes, providing the object with category names for each:
function groupByClass(data) {
return data.reduce( (acc, { fields } ) => {
(acc[fields.category_class] = acc[fields.category_class] || {
categoryClass: fields.category_class,
categoryNameList: []
}).categoryNameList.push(fields.category_name);
return acc;
}, {} );
}
// Sample data
var data = [
{"fields":{"category_class":"CAT2","category_name":"A"},"pk":1 },
{"fields":{"category_class":"CAT1","category_name":"B"},"pk":2 },
{"fields":{"category_class":"CAT1","category_name":"C"},"pk":3 },
{"fields":{"category_class":"CAT2","category_name":"D"},"pk":4 },
{"fields":{"category_class":"CAT3","category_name":"E"},"pk":5 },
{"fields":{"category_class":"CAT1","category_name":"E"},"pk":6 },
];
// Convert
var result = groupByClass(data);
// Outut
console.log(result);
// Example look-up:
console.log(result['CAT1']);
Question : Basically i want to select all categories name whose category class is CAT1 and so forth for other categories class
Solution :
function Select_CatName(catclass,array){
var CatNameList=[]
$(array).each(function(){
if(this.fields.category_class==catclass)
CatNameList.push(this.fields.category_name)
})
return CatNameList;
}
This function return the Desired Category Name List, you need to pass desired catclass and array of the data , as in this case it's your JSON.
Input :
Above function calling :
Output :
Hope It helps.

getting distinct values from array of arrays in Javascript

My data is in the following format..
var data= [['typeName', 'valueName'], ['type1', 'value1'],
['type1', 'value2'],['type2', 'value3'],['type2', 'value4']]
I wish to transform the above data to data as below..
var resultdata=[{'typeName':'type1','valueName':['value1','value2']},
{'typeName':'type2','valueName':['value3','value4']}]
Basically I pick up distinct 'typeName' values and then group 'valueName' values by 'typeName' values.
I would preferably use only knockoutjs, lodash or underscorejs as my soln already uses them but I'm open to other solutions as well..
All help is sincerely appreciated
Thanks
I think this solution using underscore should do the trick:
var result= _.chain(data)
.rest()
.groupBy( value => value[0])
.map( (value,key) => ({ [data[0][0]]: key, [data[0][1]]: _.map(value, val => val[1])}))
.value();
This solution uses rest to skip the first item in the data array (the type descriptors). The array is then grouped by the first value in the array (the type) and the mapping returns the grouping in the required form using es6 object initializer notation.
Given the result as:
var resultdata=[
{'typeName':'type1'},{'valueName':['value1','value2']},
{'typeName':'type2'},{'valueName':['value3','value4']}
]
I'm going to call 'typeName' the category and 'valueName' the items.
Since the original data look like this:
var data= [
['typeName', 'valueName'],
['type1', 'value1'],
['type1', 'value2'],
['type2', 'value3'],
['type2', 'value4']
]
It is clear there is a pattern. The first row of data is what we'll use as labels for category and items. All the remaining data represent the values being used inside category and items.
The first step is to extract the labels:
var categoryLabel = data[0][0];
var itemLabel = data[0][1];
Next, the unique categories will need to be determined, so we'll use reduce to build an array of unique categories:
var categories = data
.filter(function(row, i) { return i > 0 }) // remove the labels
.reduce(function(arrCategories, currRow) {
// Add the current rows' category if it doesn't already exist
var currCategory = currRow[0];
if (arrCategories.indexOf(currCategory) === -1) {
return arrCategories.concat(currCategory);
}
return arrCategories;
}, [])
Now that you have a set of categories, you just need to iterate over each one to find all items that belong to it:
var valuesByCategory = {};
categories.forEach(function(category) {
// find all the data items that match the category
var items = data
.filter(function(row) { return row[0] === category; })
.reduce(function(arrItems, currRow) {
var currItem = currRow[1];
if (arrItems.indexOf(currItem) === -1) {
return arrItems.concat(currItem);
}
return arrItems;
}, []);
valuesByCategory[category] = items;
});
Now that all the data has been parsed out, the only thing left to do is build the resultant array:
var resultdata = [];
// iterate through each of the categories
categories.forEach(function(category) {
// using the category label, output an object with the label and category
var categoryObj = {};
categoryObj[categoryLabel] = category;
resultdata.push(categoryObj);
// Next, create a items object containing all the values
var itemsObj = {};
itemsObj[itemLabel] = valuesByCategory[category];
resultdata.push(itemsObj);
}
and that's it :)
The best part is that you don't need any external libraries. This is all ES2015 javascript!
Here is a lodash version of Gruff Bunnies solution:
var data= [['typeName', 'valueName'], ['type1', 'value1'], ['type1', 'value2'],['type2', 'value3'],['type2', 'value4']]
var names = data[0]
var values = _.tail(data)
console.log(JSON.stringify(
_(values)
.groupBy(0)
.map( (value, key) => ({ [names[0]]: key, [names[1]]: _.map(value, 1)}) )
.value()
))
https://jsfiddle.net/nmf1fdf5/

How to filter out Duplicates of an array of objects

I have an array of objects which look like this:
$scope.SACCodes = [
{'code':'023', 'description':'Spread FTGs', 'group':'footings'},
{'code':'024', 'description':'Mat FTGs', 'group':'footings'},
{'code':'025', 'description':'CONT. FTGs', 'group':'footings'},
{'code':'025', 'description':'CONT. FTGs', 'group':'levels'},
{'code':'023', 'description':'Trucks', 'group':'footings'}
]
I need to filter out duplicates where the code and the group are duplicates. If only one of them is the same it shouldn't filter it out.
Here is another approach based on TLindig's answer to a similar question.
Add a filter method to the scope:
$scope.onlyUnique = function(value, index, self) {
codes = self.map(function(c) {return c.code});
groups = self.map(function(c) {return c.group});
return codes.indexOf(value.code) === index || groups.indexOf(value.group) === index;
Call the filter method in your ng-repeat or wherever you want the unique values:
<div ng-repeat="c in SACCodes.filter(onlyUnique)">code: {{c.code}} desc: {{c.description}} group: {{c.group}}</div>
Output:
code: 023 desc: Spread FTGs group: footings
code: 024 desc: Mat FTGs group: footings
code: 025 desc: CONT. FTGs group: footings
code: 025 desc: CONT. FTGs group: levels
The ES6 way.
var m = new Map();
SACCodes.forEach ( function( item ) {
var key = item.code + item.group;
if ( !m.has( key ) ){
m.set( key, item );
}
});
SACCodes= [ ...m.values() ];
This uses a helper hash to note which combination of code and group have already been processed. Only if it finds a hitherto unused combination does it add it to the retVal array;
function dedup() {
var dups = {};
var retVal = [];
for (var i = 0; i < $scope.SACCodes.length; i++) {
var sCode = $scope.SACCodes[i];
var key = sCode.code +'/'+ sCode.group;
if (!dups[key]) {
retVal.push (sCode);
dups[key] = sCode;
}
}
return retVal;
}
See working example
Couple of years down the road you could use Object.values(dups); instead of retVal and thereby shorten the code.

Categories