I have a javascript object (I actually get the data through an ajax request):
var data = {};
I have added some stuff into it:
data[0] = { "ID": "1"; "Status": "Valid" }
data[1] = { "ID": "2"; "Status": "Invalid" }
Now I want to remove all objects with an invalid status (but keep everything the ordering same):
var tempData = {};
for ( var index in data ) {
if ( data[index].Status == "Valid" ) {
tempData.push( data );
}
}
data = tempData;
In my mind, all of this should work, but I am getting an error that tempData.push is not a function. I understand why it isn't the same as an array, but what could I do otherwise?
push() is for arrays, not objects, so use the right data structure.
var data = [];
// ...
data[0] = { "ID": "1", "Status": "Valid" };
data[1] = { "ID": "2", "Status": "Invalid" };
// ...
var tempData = [];
for ( var index=0; index<data.length; index++ ) {
if ( data[index].Status == "Valid" ) {
tempData.push( data );
}
}
data = tempData;
Objects does not support push property, but you can save it as well using the index as key,
var tempData = {};
for ( var index in data ) {
if ( data[index].Status == "Valid" ) {
tempData[index] = data;
}
}
data = tempData;
I think this is easier if remove the object if its status is invalid, by doing.
for(var index in data){
if(data[index].Status == "Invalid"){
delete data[index];
}
}
And finally you don't need to create a var temp –
You must make var tempData = new Array();
Push is an Array function.
Javascript programming language supports functional programming paradigm so you can do easily with these codes.
var data = [
{"Id": "1", "Status": "Valid"},
{"Id": "2", "Status": "Invalid"}
];
var isValid = function(data){
return data.Status === "Valid";
};
var valids = data.filter(isValid);
I hope this one might help you.
let data = [];
data[0] = { "ID": "1", "Status": "Valid" };
data[1] = { "ID": "2", "Status": "Invalid" };
let tempData = [];
tempData= data.filter((item)=>item.Status!='Invalid')
console.log(tempData)
tempData.push( data[index] );
I agree with the correct answer above, but.... your still not giving the index value for the data that you want to add to tempData. Without the [index] value the whole array will be added.
I assume that REALLY you get object from server and want to get object on output
Object.keys(data).map(k=> data[k].Status=='Invalid' && delete data[k])
var data = { 5: { "ID": "0", "Status": "Valid" } }; // some OBJECT from server response
data = { ...data,
0: { "ID": "1", "Status": "Valid" },
1: { "ID": "2", "Status": "Invalid" },
2: { "ID": "3", "Status": "Valid" }
}
// solution 1: where output is sorted filtred array
let arr=Object.keys(data).filter(k=> data[k].Status!='Invalid').map(k=>data[k]).sort((a,b)=>+a.ID-b.ID);
// solution2: where output is filtered object
Object.keys(data).map(k=> data[k].Status=='Invalid' && delete data[k])
// show
console.log('Object',data);
console.log('Array ',arr);
Mozilla actually shows you how to handle objects with push by chaining push to the call method:
"push is intentionally generic, and we can use that to our advantage. Array.prototype.push can work on an object just fine, as this example shows.
Note that we don't create an array to store a collection of objects. Instead, we store the collection on the object itself and use call on Array.prototype.push to trick the method into thinking we are dealing with an array—and it just works, thanks to the way JavaScript allows us to establish the execution context in any way we want.
const obj = {
length: 0,
addElem(elem) {
// obj.length is automatically incremented
// every time an element is added.
[].push.call(this, elem);
},
};
// Let's add some empty objects just to illustrate.
obj.addElem({});
obj.addElem({});
console.log(obj.length);
// → 2
Note that although obj is not an array, the method push successfully incremented obj's length property just like if we were dealing with an actual array."
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
You are getting that error because data.push only works with array, not object.
So here is what you can do:
var data = {};
data[0] = { "ID": "1"; "Status": "Valid" }
data[1] = { "ID": "2"; "Status": "Invalid" }
var tempData = {};
for ( var index in data ) {
if ( data[index].Status == "Valid" ) {
tempData[index] = data[index];
}
}
data = tempData;
Do :
var data = new Array();
var tempData = new Array();
Related
Need help figuring this out..
I want to create nested Javascript Object dynamically..
I have got a key, which has multiple values that needs to be nested per value in an array.
For example:
{
"name": [{
"desc": "A",
"age": 26,
"name": [{
"desc": "B",
"age": 12,
"name": [{
"desc": "C",
"age": 48
}]
}]
}]
}
So far i have this:
var data = [[{desc:"A", age:26}], [{desc:"B", age:12}], [{desc:"C", age:48}]]
const name = "name"
var json = {};
var current = json;
for (var i = 0; i < data.length; i++) {
current[name] = data[i];
current = current[name];
}
console.log(JSON.stringify(json));
Which only returns the first item in the data array.
{
"name": [{
"desc": "A",
"age": 26
}]
}
Below code does what you want:
var data = [[{desc:"A", age:26}], [{desc:"B", age:12}], [{desc:"C", age:48}]]
const value = data.reverse().reduce((acc, item) => {
return [{
...item[0],
name: acc
}]
});
console.log(value);
Though if you just had an array of objects instead of an array of arrays containing objects this would be slightly easier:
var data = [{desc:"A", age:26}, {desc:"B", age:12}, {desc:"C", age:48}]
data.reverse().reduce((acc, item) => {
return [{
...item,
name: acc
}]
});
You need to use recursion in this case since your are creating children.
In this code, we reduce the size of the array by removing the first element and passing it back to the same function
var data = [
[{desc:"A", age:26}],
[{desc:"B", age:12}],
[{desc:"C", age:48}]
]
function recursivelyAssignData(array) {
// we get the current element, to assign it a property "name",
const currentElement = array[0][0]
// we remove the first element, so it wont be pass to subsequent call of the function.
array.shift();
// if this is the last element, we don't want to assign the property "name" to it.
return array.length >= 1 ? Object.assign(currentElement, {
// we assign the value of same function, but with a different array.
name: recursivelyAssignData(array),
}) : currentElement;
}
const result = {request: recursivelyAssignData(data)};
console.log('results:', result , 'json:', JSON.stringify(result ));
P.S
Recursion might not be the most intuitive thing in the world, if you have trouble understand it, please ask question.
You are almost there. Since the values are inserted as first item in an array, use index 0 to access them.
const data = [[{desc:"A", age:26}], [{desc:"B", age:12}], [{desc:"C", age:48}]];
const name = "name";
let result = {
[name]: data[0]
};
let obj = result;
for (let i = 1; i < data.length; i++) {
let current = obj[name][0];
current[name] = data[i];
obj = current;
}
console.log(result);
I am trying to get a value from an array within an object.
This is the data:
{
"Order Number":102541029,
"Tracking Number":192048236154915,
"Secondary Tracking":87350125235,
"Items":[{
"SKU":"0200-02-01-NP-P-00",
"QTY":4
},
{
"SKU":"0120-02-01-XP-T-00",
"QTY":2
}]
}
If I wanted, say, the quantity of the second item (SKU 0120-02-01-XP-T-00), how would I select this?
I've tried a few things like this:
var skuQty = datain.items.['0120-02-01-XP-T-00'].['QTY'];
That's the idea, but I am not using the right syntax obviously. Any help here?
Jesse
This is how you scroll through the quantities:
var yourObject = {
"Order Number":102541029,
"Tracking Number":192048236154915,
"Secondary Tracking":87350125235,
"Items":[{
"SKU":"0200-02-01-NP-P-00",
"QTY":4
},
{
"SKU":"0120-02-01-XP-T-00",
"QTY":2
}]
};
var items = yourObject.Items;
for (var i = 0; i < items.length; i ++){
console.log(items[i].QTY);
}
In general you can access an array with its index something like this: arr[i] and object can be accessed by it's key name:
`yourObject.yourkey`
in JavaScript, an array = [1,2,3] can be accessed with array[index].
If you have an array that looks like this: array = [{ prop: propValue }], then this is virtually the same as obj = { prop: propValue }; array = [ obj ], so what you need to do to get propValue is array[ 0 ]['prop'].
For your specific case, you'd need
datain.Items[1]['SKU'];
Now, what you actually want to do is filter through the array items until the above value is "0120-02-01-XP-T-00"
This is literally filtering an array:
datain.Items.filter( function( obj ){ return obj['SKU'] === "0120-02-01-XP-T-00" } )[0]['QTY']
The key is that array.filter( fn ) returns a new array of values for which fn( item [, other parameters you don't need to worry about] ) is true (or truthy). At that point, you only need the first item, at index = 0
First of all, select the specified object - in your case - data.
Then select specified key from the data object - in your case - Items.
Since Items is an array with two objects, you have to specify which one of them you are interested in. In your case - the second one with index 1.
data.Items[1] is an object holding two positions. You are interested in the second one - so you just type that key name - QTY.
Adding it up together - data.Items[1].QTY.
var data = {
"Order Number": 102541029,
"Tracking Number": 192048236154915,
"Secondary Tracking": 87350125235,
"Items": [{
"SKU": "0200-02-01-NP-P-00",
"QTY": 4
}, {
"SKU": "0120-02-01-XP-T-00",
"QTY": 2
}]
};
console.log(data.Items[1].QTY)
This is how you get it:
Object {Order Number: 102541029, Tracking Number: 192048236154915, Secondary Tracking: 87350125235, Items: Array[2]}
obj.Items[0]
Object {SKU: "0200-02-01-NP-P-00", QTY: 4}
obj.Items[0].QTY
obj = {
"Order Number":102541029,
"Tracking Number":192048236154915,
"Secondary Tracking":87350125235,
"Items":[{
"SKU":"0200-02-01-NP-P-00",
"QTY":4
},
{
"SKU":"0120-02-01-XP-T-00",
"QTY":2
}]
};
console.log(obj.Items[0].QTY);
You can use Array.prototype.filter(), at callback return o.SKU === "0120-02-01-XP-T-00", where o is current object in iteration use bracket notation to select element at index 0 of returned array
var QTY = data.Items.filter(function(o) {
return o.SKU === "0120-02-01-XP-T-00"
})[0]["QTY"];
You can alternatively utilize destructuring assignment
var [, {QTY}] = data.Items;
Because items is an array, you need to select the appropriate index of the array, in this case 1.
For example:
var skuQty = datain.items[1].QTY;
Make a function to find order items for a given SKU:
var findOrderItem = function (order, sku) {
if (order && order.Items) {
for (var i = 0; i < order.Items.length; i++) {
if (order.Items[i].SKU == sku) {
return order.Items[i];
}
}
}
return null;
};
var myOrder = {
"Order Number": 102541029,
"Tracking Number": 192048236154915,
"Secondary Tracking": 87350125235,
"Items": [
{
"SKU": "0200-02-01-NP-P-00",
"QTY": 4
},
{
"SKU": "0120-02-01-XP-T-00",
"QTY": 2
}
]
};
var sku = "0120-02-01-XP-T-00";
var item = findOrderItem(myOrder, sku);
var qty = 0;
if (item) {
qty = item.QTY;
}
console.log("item qty", qty);
i have serialize array like this
rate_3=26&rate_8=67&rate_12=98 etc..,
now i need to change this array as json type
{
"ID": "3",
"Rate": "26"
},
{
"ID": "8",
"Rate": "67"
},
{
"ID": "3",
"Rate": "26"
} ..,
etc
so i tried like this but its not working... please some one help me.
var o = {};
var a = table.$('input, select').serialize();
$.each(a, function()
{
if (o[this.name] !== undefined)
{
if (!o[this.name].push)
{
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
}
else
{
o[this.name] = this.value || '';
}
});
return o;
i m using datatable so i just need to get Datatables serialize array only for that used this line
var a = table.$('input, select').serialize();
even i tried with json2.js also but when i use json2.js it forcing the page to submit
var data_2 = JSON.stringify(block_form.serializeArray());
Simple method is to map over the results of a regex match, pushing new objects into the resulting array:
var out = str.match(/\d+=\d+/g).map(function (el) {
var arr = el.split('=');
return { id: arr[0], rate: arr[1] };
});
DEMO
Convert the output array to JSON with JSON.stringify(out).
If your data format is reliably in the rate_N=X& format, you can use simple string splitting to parse out the values. This appears to be similar to how query strings are formatted and, if that's the case, you shouldn't run into (m)any unusual entities.
First, you'll want to break each key-value pair apart (on the &). Then split each pair on the = to produce the key and value. You'll need to parse the ID out of the key (cut the rate_ off the front), which substr will work well for.
var data = "rate_3=26&rate_8=67&rate_12=98";
var pairs = data.split('&').reduce(function(collect, pair) {
var kv = pair.split('=');
var name = kv[0].substr(kv[0].indexOf('_') + 1);
collect.push({
id: name,
rate: kv[1]
});
return collect;
}, []);
document.getElementById('results').textContent = JSON.stringify(pairs);
<pre id="results"></pre>
http://jsfiddle.net/43hnftaf/
var str = 'rate_3=26&rate_8=67&rate_12=98'
var arr = str.split('&').map(function(element) {
return element.replace(/^rate_/, '');
}).map(function(element) {
var elements = element.split('=');
return {
"ID" : elements[0],
"Rate" : elements[1]
};
});
console.log(arr);
I am trying to push
data.push({"country": "IN"});
as new id and value to a json string. but it gives the following error
Uncaught TypeError: data.push is not a function
data{"name":"ananta","age":"15"}
Advance Thanks for your reply
To use the push function of an Array your var needs to be an Array.
Change data{"name":"ananta","age":"15"} to following:
var data = [
{
"name": "ananta",
"age": "15",
"country": "Atlanta"
}
];
data.push({"name": "Tony Montana", "age": "99"});
data.push({"country": "IN"});
..
The containing Array Items will be typeof Object and you can do following:
var text = "You are " + data[0]->age + " old and come from " + data[0]->country;
Notice: Try to be consistent. In my example, one array contained object properties name and age while the other only contains country. If I iterate this with for or forEach then I can't always check for one property, because my example contains Items that changing.
Perfect would be: data.push({ "name": "Max", "age": "5", "country": "Anywhere" } );
So you can iterate and always can get the properties, even if they are empty, null or undefined.
edit
Cool stuff to know:
var array = new Array();
is similar to:
var array = [];
Also:
var object = new Object();
is similar to:
var object = {};
You also can combine them:
var objectArray = [{}, {}, {}];
Your data variable contains an object, not an array, and objects do not have the push function as the error states. To do what you need you can do this:
data.country = 'IN';
Or
data['country'] = 'IN';
Also make sure that the name of the variable is not some kind of a language keyword.
For instance, the following produces the same type of error:
var history = [];
history.push("what a mess");
replacing it for:
var history123 = [];
history123.push("pray for a better language");
works as expected.
you can use push method only if the object is an array:
var data = new Array();
data.push({"country": "IN"}).
OR
data['country'] = "IN"
if it's just an object you can use
data.country = "IN";
I think you set it as
var data = [];
but after some time you made it like:
data = 'some thing which is not an array';
then
data.push('') will not work as it is not an array anymore.
One things to remember push work only with array[] not object{}.
If you want to add object o inside inside n like that :
a = {
b:"c",
D:"e",
F: {
g:"h",
I:"j",
k: {
l:"m"
}
}
}
a.F.k.n = { o: "p" };
console.log(a);
Try This Code $scope.DSRListGrid.data = data; this one for source data
for (var prop in data[0]) {
if (data[0].hasOwnProperty(prop)) {
$scope.ListColumns.push(
{
"name": prop,
"field": prop,
"width": 150,
"headerCellClass": 'font-12'
}
);
}
}
console.log($scope.ListColumns);
make sure you push into an Array only
and if their is error like Uncaught TypeError: data.push is not a function**
then check for type of data
you can do this by consol.log(data)
hope this will help
let dataArray = [{'id':1,'code':'ABC'},{'id':1,'code':'ABC'},{'id':2,'code':'ABC'}]
let obj = {};
dataArray.forEach(task => {
task.id in obj ? obj[task.employee_id].push(task):
obj = {
...obj,
[task.employee_id]: [task],
}
});
I'm playing around with arrays trying to understand them more since I tend to work with them alot lately.
I got this case where I want to search an array and compare it's element values to another array which contains values of some selected filters.
For example if I select 3 filters, I want later to write matches in new array - only those which match all 3 filters.
For easier understanding I set up an example on http://jsfiddle.net/easwee/x8U4v/36/
Code is:
var workItems = [
{ "id": 2616, "category": ".category-copy .category-beauty .category-fashion"}, //this is a match
{ "id": 1505, "category": ".category-beauty"}, // NOT
{ "id": 1500, "category": ".category-beauty .category-fashion"}, // NOT
{ "id": 692, "category": ".category-stills .category-retouching"}, // NOT
{ "id": 593, "category": ".category-beauty .category-capture .category-fashion .category-product .category-stills .category-stills-retouching "}, // NOT
{ "id": 636, "category": ".category-beauty .category-copy .category-fashion"}, //this is a match
{ "id": 547, "category": ".category-fashion .category-lifestyle .category-stills .category-stills-retouching "}, // NOT
{ "id": 588, "category": ".category-capture .category-recent-work .category-copy .category-beauty .category-fashion"} //this is a match
];
var filtersArray = [".category-beauty", ".category-fashion", ".category-copy"];
var i;
for (i = 0; i < filtersArray.length; ++i) {
var searchString = filtersArray[i];
console.log('Searching for: ' + searchString);
var filtered = $(workItems).filter(function(){
return this.category.indexOf(searchString);
});
}
console.log('Filtered results: ' + JSON.stringify(filtered, null, 4));
I also tried with
filtered = $.grep(workItems, function(element, index){
return element.category.indexOf(filtersArray[i]);
}, true);
but it matches only the first filter and only if it's at the begining of workItems.category
I've tried many different solutions but can't really make this work. What function should I use to return the desired result?
You can use .filter() method of the Array object:
var filtered = workItems.filter(function(element) {
// Create an array using `.split()` method
var cats = element.category.split(' ');
// Filter the returned array based on specified filters
// If the length of the returned filtered array is equal to
// length of the filters array the element should be returned
return cats.filter(function(cat) {
return filtersArray.indexOf(cat) > -1;
}).length === filtersArray.length;
});
http://jsfiddle.net/6RBnB/
Some old browsers like IE8 doesn't support .filter() method of the Array object, if you are using jQuery you can use .filter() method of jQuery object.
jQuery version:
var filtered = $(workItems).filter(function(i, element) {
var cats = element.category.split(' ');
return $(cats).filter(function(_, cat) {
return $.inArray(cat, filtersArray) > -1;
}).length === filtersArray.length;
});
You can use .filter() with boolean operators ie &&:
var find = my_array.filter(function(result) {
return result.param1 === "srting1" && result.param2 === 'string2';
});
return find[0];
The best way would be to have an array of values to search and then loop the data.
const ids = [1,2,3];
const products = DATA.filter((item) => ids?.includes(item.id));
this trick will help if anyone want to apply filter on the base of more than of property of object.
searchCustomers(){
let tempCustomers = this.customers
if (this.searchValue != '' && this.searchValue) {
tempCustomers = tempCustomers.filter((item) => {
return item.name
.toUpperCase()
.includes(this.searchValue.toUpperCase()) || item.customer_no
.toUpperCase()
.includes(this.searchValue.toUpperCase()) || item.mobno
.toUpperCase()
.includes(this.searchValue.toUpperCase())
})
}
return tempCustomers;
}