Better way to remove item from the array - javascript

I have a jquery array.In here i want to remove WORLD NEWS item.
My array comes like this,
[Object { NewsType="WORLD NEWS", NoOfHours=2},
Object { NewsType="LOCAL NEWS", NoOfHours=1},
Object { NewsType="SPORTS NEWS", NoOfHours=2}]
i have tried it like this,
var remItem ="WORLD" ;
NewsArray.splice($.inArray(remItem, NewsArray), 1);
but in here i hardcoded news,it's not good because sometimes it comes as a world or global or any other similar name.
How do i solve this problem?

Your jSON structure should not contain = instead it should be in key:value pair.You can filter this by using grep fun
var data= [
{ NewsType:"WORLD NEWS", NoOfHours:2},
{ NewsType:"LOCAL NEWS", NoOfHours:1},
{ NewsType:"SPORTS NEWS", NoOfHours:2}
]
var target = "WORLD NEWS";
data = jQuery.grep(data, function(e){
return e.NewsType != target;
});

try replacing
NewsArray.splice($.inArray(remItem, NewsArray), 1);
with
NewsArray = NewsArray.filter(function(val){return val.NewsType.indexOf(remItem)== -1});
This will filter out items which has WORLD in it.

Try using filter
var obj = [{ NewsType:"WORLD NEWS", NoOfHours:2},{ NewsType:"LOCAL NEWS", NoOfHours:1},{ NewsType:"SPORTS NEWS", NoOfHours:2}];
var rez = obj.filter(function(v){
return v.NewsType != "WORLD NEWS";
});

Reffer this link
var y = ['WORLD NEWS','LOCAL NEWS', 'SPORTS NEWS']
var removeItem = 'WORLD NEWS';
y = jQuery.grep(y, function(value) {
return value != removeItem;
});

You can use Array.prototype.indexOf(), $.grep()
arr.splice(arr.indexOf($.grep(arr, function(obj) {
return obj.NewsType === "WORLD NEWS"
})[0]), 1);
var arr = [{
NewsType: "WORLD NEWS",
NoOfHours: 2
}, {
NewsType: "LOCAL NEWS",
NoOfHours: 1
}, {
NewsType: "SPORTS NEWS",
NoOfHours: 2
}];
arr.splice(arr.indexOf($.grep(arr, function(obj) {
return obj.NewsType === "WORLD NEWS"
})[0]), 1);
console.log(JSON.stringify(arr, null, 2))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

Related

How to use _.where method from underscore.js library for more elaborated searchs

var a = {
"title": "Test 1",
"likes": {
"id": 1
}
}
var b = {
"title": "Test 2",
"likes": {
"id": 2
}
}
var c = [a, b];
var d = _.where(c, {
"title": "Test 2",
"likes": {
"id": 2
}
});
//d => outputs an empty array []
In this situation i would expect to get the reference to object in memory but d
but actually it just works on root properties.
_.where(c, {title: "Test 2"});
=> outputs [object]
where object is the reference for c[1];
EDIT:
found a possible solution using _.filter()
_.filter( c, function(item){
if (item.title == "Test 1" && item.likes.id == 1){
return item;
}
})
outputs => [object] with reference for variable a
_.filter is the right way to do this, _.where is just a _.filter shortcut for filtering on simple key/value pairs. You can see this from the source:
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_.where = function(obj, attrs, first) {
if (_.isEmpty(attrs)) return first ? void 0 : [];
return _[first ? 'find' : 'filter'](obj, function(value) {
for (var key in attrs) {
if (attrs[key] !== value[key]) return false;
}
return true;
});
};
The docs could be a little more explicit but at least the comment in the source is clear.

Get specific object by id from array of objects in AngularJS

I have a JSON file containing some data I d like to access on my AngularJS website. Now what I want is to get only one object from the array. So I d like for example Item with id 1.
The data looks like this:
{ "results": [
{
"id": 1,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] }
I'd like to load the data with AngularJS $http functionality like this:
$http.get("data/SampleData.json");
which is working. But how can I now get a specific data object (by id) from the array I get from $http.get ?
Using ES6 solution
For those still reading this answer, if you are using ES6 the find method was added in arrays. So assuming the same collection, the solution'd be:
const foo = { "results": [
{
"id": 12,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] };
foo.results.find(item => item.id === 2)
I'd totally go for this solution now, as is less tied to angular or any other framework. Pure Javascript.
Angular solution (old solution)
I aimed to solve this problem by doing the following:
$filter('filter')(foo.results, {id: 1})[0];
A use case example:
app.controller('FooCtrl', ['$filter', function($filter) {
var foo = { "results": [
{
"id": 12,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] };
// We filter the array by id, the result is an array
// so we select the element 0
single_object = $filter('filter')(foo.results, function (d) {return d.id === 2;})[0];
// If you want to see the result, just check the log
console.log(single_object);
}]);
Plunker: http://plnkr.co/edit/5E7FYqNNqDuqFBlyDqRh?p=preview
For anyone looking at this old post, this is the easiest way to do it currently. It only requires an AngularJS $filter. Its like Willemoes answer, but shorter and easier to understand.
{
"results": [
{
"id": 1,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
]
}
var object_by_id = $filter('filter')(foo.results, {id: 2 })[0];
// Returns { id: 2, name: "Beispiel" }
WARNING
As #mpgn says, this doesn't work properly. This will catch more results. Example: when you search 3 this will catch 23 too
personally i use underscore for this kind of stuff... so
a = _.find(results,function(rw){ return rw.id == 2 });
then "a" would be the row that you wanted of your array where the id was equal to 2
I just want to add something to Willemoes answer.
The same code written directly inside the HTML will look like this:
{{(FooController.results | filter : {id: 1})[0].name }}
Assuming that "results" is a variable of your FooController and you want to display the "name" property of the filtered item.
You can use ng-repeat and pick data only if data matches what you are looking for using ng-show
for example:
<div ng-repeat="data in res.results" ng-show="data.id==1">
{{data.name}}
</div>
You can just loop over your array:
var doc = { /* your json */ };
function getById(arr, id) {
for (var d = 0, len = arr.length; d < len; d += 1) {
if (arr[d].id === id) {
return arr[d];
}
}
}
var doc_id_2 = getById(doc.results, 2);
If you don't want to write this messy loops, you can consider using underscore.js or Lo-Dash (example in the latter):
var doc_id_2 = _.filter(doc.results, {id: 2})[0]
If you want the list of items like city on the basis of state id then use
var state_Id = 5;
var items = ($filter('filter')(citylist, {stateId: state_Id }));
Unfortunately (unless I'm mistaken), I think you need to iterate over the results object.
for(var i = 0; i < results.length; i += 1){
var result = results[i];
if(result.id === id){
return result;
}
}
At least this way it will break out of the iteration as soon as it finds the correct matching id.
Why complicate the situation? this is simple write some function like this:
function findBySpecField(data, reqField, value, resField) {
var container = data;
for (var i = 0; i < container.length; i++) {
if (container[i][reqField] == value) {
return(container[i][resField]);
}
}
return '';
}
Use Case:
var data=[{
"id": 502100,
"name": "Bərdə filialı"
},
{
"id": 502122
"name": "10 saylı filialı"
},
{
"id": 503176
"name": "5 sayli filialı"
}]
console.log('Result is '+findBySpecField(data,'id','502100','name'));
output:
Result is Bərdə filialı
The only way to do this is to iterate over the array. Obviously if you are sure that the results are ordered by id you can do a binary search
$scope.olkes = [{'id':11, 'name':'---Zəhmət olmasa seçim edin---'},
{'id':15, 'name':'Türkyə'},
{'id':45, 'name':'Azərbaycan'},
{'id':60, 'name':'Rusya'},
{'id':64, 'name':'Gürcüstan'},
{'id':65, 'name':'Qazaxıstan'}];
<span>{{(olkes | filter: {id:45})[0].name}}</span>
output: Azərbaycan
If you can, design your JSON data structure by making use of the array indexes as IDs. You can even "normalize" your JSON arrays as long as you've no problem making use of the array indexes as "primary key" and "foreign key", something like RDBMS. As such, in future, you can even do something like this:
function getParentById(childID) {
var parentObject = parentArray[childArray[childID].parentID];
return parentObject;
}
This is the solution "By Design". For your case, simply:
var nameToFind = results[idToQuery - 1].name;
Of course, if your ID format is something like "XX-0001" of which its array index is 0, then you can either do some string manipulation to map the ID; or else nothing can be done about that except through the iteration approach.
I know I am too late to answer but it's always better to show up rather than not showing up at all :). ES6 way to get it:
$http.get("data/SampleData.json").then(response => {
let id = 'xyz';
let item = response.data.results.find(result => result.id === id);
console.log(item); //your desired item
});
The simple way to get (one) element from array by id:
The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.
function isBigEnough(element) {
return element >= 15;
}
var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130 only one element - first
you don't need to use filter() and catch first element xx.filter()[0] like in comments above
The same for objects in array
var foo = {
"results" : [{
"id" : 1,
"name" : "Test"
}, {
"id" : 2,
"name" : "Beispiel"
}, {
"id" : 3,
"name" : "Sample"
}
]};
var secondElement = foo.results.find(function(item){
return item.id == 2;
});
var json = JSON.stringify(secondElement);
console.log(json);
Of course if you have multiple id then use filter() method to get all objects.
Cheers
function isBigEnough(element) {
return element >= 15;
}
var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130 only one element - first
var foo = {
"results" : [{
"id" : 1,
"name" : "Test"
}, {
"id" : 2,
"name" : "Beispiel"
}, {
"id" : 3,
"name" : "Sample"
}
]};
var secondElement = foo.results.find(function(item){
return item.id == 2;
});
var json = JSON.stringify(secondElement);
console.log(json);
projectDetailsController.controller('ProjectDetailsCtrl', function ($scope, $routeParams, $http) {
$http.get('data/projects.json').success(function(data) {
$scope.projects = data;
console.log(data);
for(var i = 0; i < data.length; i++) {
$scope.project = data[i];
if($scope.project.name === $routeParams.projectName) {
console.log('project-details',$scope.project);
return $scope.project;
}
}
});
});
Not sure if it's really good, but this was helpful for me..
I needed to use $scope to make it work properly.
use $timeout and run a function to search in "results" array
app.controller("Search", function ($scope, $timeout) {
var foo = { "results": [
{
"id": 12,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] };
$timeout(function () {
for (var i = 0; i < foo.results.length; i++) {
if (foo.results[i].id=== 2) {
$scope.name = foo.results[i].name;
}
}
}, 10);
});
I would iterate over the results array using an angularjs filter like this:
var foundResultObject = getObjectFromResultsList(results, 1);
function getObjectFromResultsList(results, resultIdToRetrieve) {
return $filter('filter')(results, { id: resultIdToRetrieve }, true)[0];
}

Micro template with nested arrays

I am trying to incorporate a micro template into a plugin I am building. I have gotten everything good and all, but I am having issues when it comes to the nested array in the data. Thank you very much in advance for your help. Here is the stripped code:
var locations = [{
"name": "Disneyland California",
"address": "1313 North Harbor Boulevard"
},
{
"name": "Walt Disney World Resort",
"address": "1503 Live Oak Ln"
}],
tmplData = [{
location: locations[0],
foo: "bar"
}],
template = "Shipping From:<br><b>{{location.name}}, {{foo}}",
attachTemplateToData;
attachTemplateToData = function(template, data) {
var i = 0,
len = data.length,
fragment = '';
function replace(obj) {
var t, key, reg;
for (key in obj) {
reg = new RegExp('{{' + key + '}}', 'ig');
t = (t || template).replace(reg, obj[key]);
}
return t;
}
for (; i < data.length; i++) {
fragment += replace(data[i]);
}
console.log(fragment);
};
attachTemplateToData(template, tmplData);
Logs:
bar,{{location.name}}
As you can see in the console.log that 'foo' comes out just fine, but I also need to get the 'location.name' ("Disneyland California") to render as well. I know its going to be a nested loop, but I cannot for the life of me figure out the syntax. BTW, the templating solution came from here: http://net.tutsplus.com/tutorials/javascript-ajax/create-a-makeshift-javascript-templating-solution/
Thanks!
EDIT:::
I am looking to make ANY property of the locations object able to be put into the template. So for instance if the user decided they want to add locations.city or locations.foo to the array, then in the template, they would just have to go {{location.city}} or {{location.foo}}.
I HAVE been able to achieve this through the use of jQuery's tmpl plugin, but I don't need all of what that has to offer. I would like a VERY stripped version like I have, to only deal with the said instances. Here is what I did with the tmpl plugin (which works):
tmplData = [{
locations: settings.locations[i]
}];
var tmplMarkup = "Shipping From:<br><b>${locations.name}, ${locations.city}, ${locations.state}</b>";
$.template("deTemplate", tmplMarkup);
$.tmpl("deTemplate", tmplData).appendTo("#deResults");
What you need is to change template recognition to match not only {{prop}} in your matching code , but also {{prop.something}}
you can do this adding another if statement with new regexp.
instead of this:
var locations = [{
"name": "Disneyland California",
"address": "1313 North Harbor Boulevard"
},
{
"name": "Walt Disney World Resort",
"address": "1503 Live Oak Ln"
}],
tmplData = [{
location: locations[0],
foo: "bar"
}],
template = "Shipping From:<br><b>{{location.name}}, {{foo}}",
attachTemplateToData;
Try this:
var locations = [{
name: "Disneyland California",
address: "1313 North Harbor Boulevard"
},
{
name: "Walt Disney World Resort",
address: "1503 Live Oak Ln"
}],
tmplData = [{
location: locations[0].name,
foo: "bar"
}],
template = "Shipping From:<br><b>{{location}}, {{foo}}",
attachTemplateToData;
Really it is just the .name needs to be about 4 lines up! :)
Thank you for your input vittore, I have finally figured out the code. Here is the extra if statement and regEx that I needed to have, also I found that I need the .hasOwnProperty function in there too:
for(subKey in obj[key]){
if (obj[key].hasOwnProperty(subKey)) {
reg = new RegExp('{{'+key+'.'+subKey+'}}');
t = (t || template).replace(reg, obj[key][subKey]);
}
}
Here is the completed code:
var locations = [{
"name": "Disneyland California",
"address": "1313 North Harbor Boulevard"
},
{
"name": "Walt Disney World Resort",
"address": "1503 Live Oak Ln"
}],
tmplData = [{
location: locations[1],
foo: "bar"
}],
template = "Shipping From:<br><b>{{location.address}}, {{foo}}",
attachTemplateToData;
attachTemplateToData = function(template, data) {
var i = 0,
j = 0,
len = data.length,
fragment = '';
function replace(obj) {
var t, key, subKey, subSubKey, reg;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
reg = new RegExp('{{' + key + '}}', 'ig');
t = (t || template).replace(reg, obj[key]);
for(subKey in obj[key]){
if (obj[key].hasOwnProperty(subKey)) {
reg = new RegExp('{{' + key + '.' + subKey + '}}','ig');
t = (t || template).replace(reg, obj[key][subKey]);
}
}
}
}
return t;
}
for (; i < data.length; i++) {
fragment += replace(data[i]);
}
console.log(fragment);
};
attachTemplateToData(template, tmplData);

Getting complex attribute value of object

Given json like this :
{ "rss": {
"page": 1,
"results": [{
"type": "text",
"$": 10
}],
"text": [{
"content": "Lorem ipsum dolor sit amet.",
"author": {
"name": "Cesar",
"email": "cesar#evoria.com"
},
},
{
"content": "Tema Tis rolod muspi merol.",
"author": {
"name": "Cleopatre",
"email": "cleopatre#pyramid.com"
},
}]
}
In javascript, I can retrieve value like this :
var json = JSON.parse(datajson);
$.each(json.text, function(key, val) {
// this one is ok
var content = val['content'];
// this one does not work
var authorname = val['author.name'];
});
Is this a way, given the attribute name in a string format, to retrieve the value of a complex object, for instance json.text[0].author.name?
EDIT
I would like to store the needed attributes in another object like :
[
{ dt: "Text content", dd: "content" },
{ dt: "Author name", dd: "author.name"}
]
You can split your "index" by . and loop over "segments", descending through levels on each iteration.
var obj = {
author : {
name : "AuthorName"
}
}
function get_deep_index(obj, index) {
var segments = index.split('.')
var segments_len = segments.length
var currently_at = obj
for(var idx = 0; idx < segments_len; idx++) {
currently_at = currently_at[segments[idx]]
}
return currently_at
}
console.log(get_deep_index(obj, 'author.name'))
The following should fix the problem.
var authorname = val['author']['name'];
You can also store the object itself as:
var author = val['author'];
And then later on you can index the attributes from that.
console.log(author.name, author.email)
Yent give a good hint in the comments with the eval function. I resolve my needed with this kind of code:
var json = JSON.parse(myjsonasastring);
var descriptiontobeadded = [
{ dt: "Text content", dd: "content" },
{ dt: "Author name", dd: "author.name" }
];
$.each(descriptiontobeadded, function(key, val) {
var dt = '<dt>' + val.dt + '</dt>';
description.append(dt);
var dl = '<dd>' + eval('json.' + val.dd) + '</dd>';
description.append(dl);
});

Search an array for matching attribute

I have an array, I need to return a restaurant's name, but I only know the value of its "food" attribute (not it's index number).
For example, how could I return "KFC" if I only knew "chicken"?
restaurants =
[
{"restaurant" : { "name" : "McDonald's", "food" : "burger" }},
{"restaurant" : { "name" : "KFC", "food" : "chicken" }},
{"restaurant" : { "name" : "Pizza Hut", "food" : "pizza" }}
];
for(var i = 0; i < restaurants.length; i++)
{
if(restaurants[i].restaurant.food == 'chicken')
{
return restaurants[i].restaurant.name;
}
}
you can also use the Array.find feature of es6. the doc is here
return restaurants.find(item => {
return item.restaurant.food == 'chicken'
})
In this case i would use the ECMAscript 5 Array.filter. The following solution requires array.filter() that doesn't exist in all versions of IE.
Shims can be found here: MDN Array.filter or ES5-shim
var result = restaurants.filter(function (chain) {
return chain.restaurant.food === "chicken";
})[0].restaurant.name;
for (x in restaurants) {
if (restaurants[x].restaurant.food == 'chicken') {
return restaurants[x].restaurant.name;
}
}
let restaurant = restaurants.find(element => element.restaurant.food == "chicken");
The find() method returns the value of the first element in the
provided array that satisfies the provided testing function.
as you can see in MDN Web Docs
Must be too late now, but the right version would be:
for(var i = 0; i < restaurants.restaurant.length; i++)
{
if(restaurants.restaurant[i].food == 'chicken')
{
return restaurants.restaurant[i].name;
}
}
you can use ES5 some. Its pretty first by using callback
function findRestaurent(foodType) {
var restaurant;
restaurants.some(function (r) {
if (r.food === id) {
restaurant = r;
return true;
}
});
return restaurant;
}
#Chap - you can use this javascript lib, DefiantJS (http://defiantjs.com), with which you can filter matches using XPath on JSON structures. To put it in JS code:
var data = [
{ "restaurant": { "name": "McDonald's", "food": "burger" } },
{ "restaurant": { "name": "KFC", "food": "chicken" } },
{ "restaurant": { "name": "Pizza Hut", "food": "pizza" } }
].
res = JSON.search( data, '//*[food="pizza"]' );
console.log( res[0].name );
// Pizza Hut
DefiantJS extends the global object with the method "search" and returns an array with matches (empty array if no matches were found). You can try out the lib and XPath queries using the XPath Evaluator here:
http://www.defiantjs.com/#xpath_evaluator

Categories

Resources