How can I cut the 6th object's value and paste it into the last object? Below is the result of this code :
JSON.parse(json).forEach(function(obj, idx, array) {
console.log(obj);
});
Updated: As you mentioned that if any object has an value must be cut
and moved to the last,
var array = JSON.parse(json),
index;
array.forEach(function(obj, idx) {
if(obj.itemId) {
index = idx;
}
});
if(typeof index !=="undefined") {
var tempObj = array.splice(index,1);
// adding it the end
array.push(tempObj);
}
It will remove the last element with itemId and move it to the end.
If I understand your question, you want to replace the last object with the object with type:"award".
Then I would do it like this:
JSON.parse(json).forEach(function(obj, idx, array) {
if (obj.type === "award") {
array[array.length - 1] = obj;
}
});
if the award is already the last, it will only be overwritten by itself.
Considering that your get an array of objects, iterate through all the objects and you will end up with the last object that has award in its type key.
for(var i = 0, _len = obj.length; i < _len; i += 1) {
if(obj[i].type === "award") {
ourObj = obj[i];
}
}
obj[obj.length-1] = ourObj;
James,
I have some few question just to get my understanding clear before providing an answer.
So, you want to remove the 6th item in array and want to replace that with the last item ?
The item you are going to remove is always going to be 6th item ?
Answer:
var item, items = JSON.parse(json), itemCount = items.length, obj, position;
for (var i = 0; i < itemCount; i++) {
item = items[i];
if (item.itemId) {
position = i;
}
}
if (position) {
items.push(items.splice(position, 1));
}
The code above will make sure that if the item appears at last position will also be handled. If you want to clone the object instead of referencing the old one then you need to loop through the object and update the new one like below
if (position) {
obj = items.splice(position, 1);
item = {};
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
item[property] = obj[property];
}
}
items.push(item);
}
Just filter it:
var res = JSON.parse(json).filter(function(value) {
return value.itemId == 6;
});
Use Array.prototype.splice() to remove the element you want. Push it to the end.
var arr = [];
var tgtIdx = -1;
var lastID = -1;
JSON.parse(json).forEach(function (obj, idx, array) {
if(obj.itemId !== null && obj.itemId > lastID) {
tgtIdx = idx;
lastID = obj.itemId;
}
arr.push(obj);
})
if(tgtIdx >= 0 && tgtIdx < arr.length - 1) {
arr.push(arr.splice(tgtIdx, 1)[0]);
}
Related
It's visible in the image that the array[0] and array[3], array1 and array[4] are same. I was checking why the values are duplicating but I failed. So thought to just remove if any duplicate values exists. I need to remove it from
$scope.arr array itself.
Code:
$scope.arr = [];
planReq.then(function (callplanList) {
$scope.callplanList = callplanList.data.callplans;
//console.log($scope.callplanList);
for(var i = 0; i < $scope.planMapping.length; i++){
//console.log($scope.planMapping[i].PlanScode);
for(var j = 0; j < $scope.callplanList.length; j++){
if(($scope.planMapping[i].PlanScode == $scope.callplanList[j].un_s_code) && ($scope.callplanList[j].offer_type == "REC")){
//console.log($scope.devicesList);
for(var a = 0; a < $scope.callplanList[j].upfront_cost.length; a++){
if($scope.callplanList[j].upfront_cost[a].upfront != ""){
//console.log($scope.callplanList[j].upfront_cost[a].handsetClass);
for(var k = 0; k < $scope.devicesList.length; k++){
if($scope.callplanList[j].upfront_cost[a].handsetClass == $scope.devicesList[k].device_class.toLowerCase()){
$scope.arr.push($scope.devicesList[k]);
}
}
}
}
}
}
}
console.log($scope.arr);
});
Any help would be appreciated.
Make use of filter.
Here is a simple filter, to remove duplicates from an array
Array.filter(function(elem, index, self){ return self.indexOf(elem) == index })
In your case it will be
$scope.arr = $scope.arr.filter(function(elem, index, self){
return self.indexOf(elem) == index
});
method 1:
var list =[{name:"a",age:2}, {name:"b",age:4}, {name:"c",age:6}, {name:"a",age:2}]
var arr = list.filter((elem, index, self) => self.findIndex(
(t) => {return (t.name === elem.name && t.age === elem.age)}) === index)
it return unique array based on all the properties
method 2:
If you want to remove duplicate elements from an array use the following function. Here the args are:
myArr: contain array ob objects
prop: the property of object by which the array elements should be removed
function removeDuplicates(myArr, prop) {
return myArr.filter((obj, pos, arr) => {
return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos;
});
}
It will remove the duplicates based on the elements property and return the array with unique elemnts.
ngRepeat uses $watchCollection to detect changes in the collection. When a change happens, ngRepeat then makes the corresponding changes to the DOM:
When an item is added, a new instance of the template is added to the DOM.
When an item is removed, its template instance is removed from the DOM.
When items are reordered, their respective templates are reordered in the DOM.
To minimize creation of DOM elements, ngRepeat uses a function to "keep track" of all items in the collection and their corresponding DOM elements. For example, if an item is added to the collection, ngRepeat will know that all other items already have DOM elements, and will not re-render them.
The default tracking function (which tracks items by their identity) does not allow duplicate items in arrays. This is because when there are duplicates, it is not possible to maintain a one-to-one mapping between collection items and DOM elements.
If you do need to repeat duplicate items, you can substitute the default tracking behavior with your own using the track by expression.
so you can do like this :
<div ng-repeat="n in [42, 42, 43, 43] track by $index">
{{n}}
</div>
If you want to remove duplicates from array :
function UniqueArraybyId(collection, keyname) {
var output = [],
keys = [];
angular.forEach(collection, function(item) {
var key = item[keyname];
if(keys.indexOf(key) === -1) {
keys.push(key);
output.push(item);
}
});
return output;
};
planReq.then(function (callplanList) {
$scope.callplanList = callplanList.data.callplans;
//console.log($scope.callplanList);
for(var i = 0; i < $scope.planMapping.length; i++){
//console.log($scope.planMapping[i].PlanScode);
for(var j = 0; j < $scope.callplanList.length; j++){
if(($scope.planMapping[i].PlanScode == $scope.callplanList[j].un_s_code) && ($scope.callplanList[j].offer_type == "REC")){
//console.log($scope.devicesList);
for(var a = 0; a < $scope.callplanList[j].upfront_cost.length; a++){
if($scope.callplanList[j].upfront_cost[a].upfront != ""){
//console.log($scope.callplanList[j].upfront_cost[a].handsetClass);
for(var k = 0; k < $scope.devicesList.length; k++){
if($scope.callplanList[j].upfront_cost[a].handsetClass == $scope.devicesList[k].device_class.toLowerCase()){
$scope.arr.push($scope.devicesList[k]);
}
}
}
}
}
}
}
$scope.arr = UniqueArraybyId($scope.arr ,"sub_family"); //you have to pass the key name
console.log($scope.arr);
})
Here is the fiddle :
function UniqueArraybyId(collection, keyname) {
var output = [],
keys = [];
angular.forEach(collection, function(item) {
var key = item[keyname];
if(keys.indexOf(key) === -1) {
keys.push(key);
output.push(item);
}
});
return output;
};
function test () {
var arr =[{sub_family:'j3 (2016)'},{sub_family:'j3 (2016)'},{sub_family:'j3 (2017)'}]
arr= UniqueArraybyId(arr ,"sub_family"); //you have to pass the key name
console.log(arr);
};
test();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
I think this is the best way to remove duplicates from an Array. Note that this requires ES6.
arr = Array.from(new Set(arr));
Example:
var arr = [0, 1, 1, 1, 1, 2, 3, 4, 3, 4, 2, 2, 4];
console.log(arr.join(", "));
arr = Array.from(new Set(arr));
console.log(arr.join(", "));
I am trying to compare the items in "item" array and the copyofOpList array to retrieve the data occurrences in copyofOpList
this is my try:
var _deleteUsedElement1 = function(item) {
for (var i = 0; i < item.length-1; i++){
for (var j = 0; j< $scope.copyofOpList.length-1; j++){
if (item[i].operationCode == $scope.copyofOpList[j].code) {
$scope.copyofOpList.splice(j, 1);
} } } };
$scope.compareArrays = function() {
...Get data from web Service
_deleteUsedElement1(item);
}
the copyofOpList array has 14 elements,and the item array has 2 array
but my code deletes only one occurrence (the first),so please how can I correct my code,to retrieve any occurances in the copyofOpList array comparing to the item array
thanks for help
I'd try to avoid looping inside a loop - that's neither a very elegant nor a very efficient way to get the result you want.
Here's something more elegant and most likely more efficient:
var item = [1,2], copyofOpList = [1,2,3,4,5,6,7];
var _deleteUsedElement1 = function(item, copyofOpList) {
return copyofOpList.filter(function(listItem) {
return item.indexOf(listItem) === -1;
});
};
copyofOpList = _deleteUsedElement1(item, copyofOpList);
console.log(copyofOpList);
//prints [3,4,5,6,7]
}
And since I just noticed that you're comparing object properties, here's a version that filters on matching object properties:
var item = [{opCode:1},{opCode:2}],
copyofOpList = [{opCode:1},{opCode:2},{opCode:3},{opCode:4},{opCode:5},{opCode:6},{opCode:7}];
var _deleteUsedElement1 = function(item, copyofOpList) {
var iOpCodes = item.map(function (i) {return i.opCode;});
return copyofOpList.filter(function(listItem) {
return iOpCodes.indexOf(listItem.opCode) === -1;
});
};
copyofOpList = _deleteUsedElement1(item, copyofOpList);
console.log(copyofOpList);
//prints [{opCode:3},{opCode:4},{opCode:5},{opCode:6},{opCode:7}]
Another benefit of doing it in this manner is that you avoid modifying your arrays while you're still operating on them, a positive effect that both JonSG and Furhan S. mentioned in their answers.
Splicing will change your array. Use a temporary buffer array for new values like this:
var _deleteUsedElement1 = function(item) {
var _temp = [];
for (var i = 0; i < $scope.copyofOpList.length-1; i++){
for (var j = 0; j< item.length-1; j++){
if ($scope.copyofOpList[i].code != item[j].operationCode) {
_temp.push($scope.copyofOpList[j]);
}
}
}
$scope.copyofOpList = _temp;
};
I have an array of objects, shown below. The first segment of code is within a loop where multiple objects of 'Item' are created and pushed onto the array.
Example of the problem is available here: http://jsfiddle.net/X6VML/
Notice how changing the value inside a textbox displays a duplicate item.
// class
var Item = function(label, value) {
this.Label = label;
this.Value = value;
};
var obj = new Item("My Label", "My Value");
// adds object onto array
itemArray.push(obj);
The problem I have is that the array can contain duplicate objects which I need to filter out before rending the list of objects into a table, shown below:
for (var i = 0; i < itemArray.length; i++) {
$('.MyTable').append("<tr><td>" + itemArray[i].Label + "</td><td>" + itemArray[i].Value + "</td></tr>");
}
I can identify whether it's a duplicate with the Value being the same. How can I filter the list of objects based on whether the Value already exists in the array?
Many thanks
Just don't add duplicate item in array:
var item = new Item("My Label", "My Value1");
if(!$.grep(itemArray, function(obj) { return obj.Value == item.Value; }).length)
itemArray.push(item);
If there is already an object with Value "My Value1" in itemArray, just don't add it.
A simple solution would be:
var temp = [];
$.each(itemArray, function(index, obj){
var found = false;
$.each(temp, function(tempI, tempObj){
if(tempObj.Value == obj.Value){
found = true;
return false;
}
});
if(!found){
temp.push(obj);
}
});
itemArray = temp;
console.log(itemArray);
The above is simply iterating over each object in the array, and pushing it to the temp array if it's not already there, finally it overwrites itemArray with temp.
Have you considered eliminating duplicates at the point of adding to the array? Something like this:
function UniqueItemList(){
var items = [];
this.push = function(item){
for(var i=0; i<items.length; i++){
if(items[i].Value == item.Value){
return;
}
}
items.push(item);
};
this.getList = function(){
return items;
}
}
var myList = new UniqueItemList();
myList.push(new Item('label1', 'value1'));
myList.push(new Item('label2', 'value2'));
myList.push(new Item('label1', 'value1'));
myList.push(new Item('label1', 'value1'));
console.log(myList.getList());
If you try to push a duplicate item, it will be rejected.
Demo - here it is integrated into your code.
This code would do. Modify the itemArray before forming the HTML.
var arr = {};
for ( var i=0; i < itemArray.length; i++ )
arr[itemArray[i].Value] = itemArray[i];
itemArray = new Array();
for ( key in arr )
itemArray.push(arr[key]);
I've got this handy utility function:
function uniq(ary, key) {
var seen = {};
return ary.filter(function(elem) {
var k = (key || String)(elem);
return seen[k] === 1 ? 0 : (seen[k] = 1);
})
}
where key is a function that fetches the comparison key from an element.
Applied to your use case:
uniqueItems = uniq(itemArray, function(item) { return item.Value })
var arr = [["test","1"],["demo","2"]];
// $.inArray() ???
// .splice() ???
// $.each() ???
$("code").html(JSON.stringify(arr));
If I will find matching array by "test" (unique) keyword , I will remove ["test","1"]
So arr after removed will be [["demo","2"]]
How can I do that ?
Playground : http://jsbin.com/ojoxuy/1/edit
This is what filter is for:
newArr = arr.filter(function(item) { return item[0] != "test" })
if you want to modify an existing array instead of creating a new one, just assign it back:
arr = arr.filter(function(item) { return item[0] != "test" })
Modificator methods like splice make code harder to read and debug.
You could do something like this:
function remove(oldArray, itemName) {
var new_array = [];
for(var i = 0, len = oldArray.length; i < len; i++) {
var arr = oldArray[i];
if (arr[0] != itemName) new_array.push(arr);
}
return new_array;
}
And call it like this:
var arr = [["test","1"],["demo","2"]];
var new_arr = remove(arr,'test');
I'm making assumptions here and not doing any real error checking but you get the idea.
Perhaps something like:
for(var i = 0; i < arr.length; i++) {
if(arr[i][0] == "test") {
arr.splice(i, 1);
break;
}
}
var arr = [["test","1"],["demo","2"]];
function checkArrayElements(a, index, arr) {
if(a[0]=="test"){
delete arr[index];
arr.splice(index,index+1);
}
}
arr.forEach(checkArrayElements);
$("code").html(JSON.stringify(arr));
NOTE: This removes any inner array in arr with the 0 element = "test"
Check this one
function rmEl(a,v)
{
for(var i=0;i<a.length;i++)
{
if(a[i][0]==v)
{
a.splice(i,i+1);
i=-1;
}
$("code").html(JSON.stringify(a));
}
return a;
}
So I have an array, which is populated with objects. The objects have two values, one containing a list item, and another containing a float (price). I'm trying to push the list into a DOM element, but the variable is globally undefined.
This code outputs the second array item to the console:
$('#coll-price-filter').change(function() {
var newList = [];
$('#coll-product-list li').each(function(idx, li) {
pprice = $(li).find('.coll-prod-price').html().trim().substring(1)
pprice = parseInt(pprice);
newList[idx] = {
value: $(li).wrap('<div></div>').parent().html(),
price: pprice
}
newList.sort(function(a, b){
a = a.price, b = b.price;
return a > b ? 1 : a < b ? -1 : 0;
});
});
console.log(newList[1].value);
});
However this does not
$('#coll-price-filter').change(function() {
var newList = [];
$('#coll-product-list li').each(function(idx, li) {
pprice = $(li).find('.coll-prod-price').html().trim().substring(1)
pprice = parseInt(pprice);
newList[idx] = {
value: $(li).wrap('<div></div>').parent().html(),
price: pprice
}
newList.sort(function(a, b){
a = a.price, b = b.price;
return a > b ? 1 : a < b ? -1 : 0;
});
});
i = newList.length;
while (i > 0) {
console.log(newList[i].listItem);
i--;
}
});
So it appears that the while loop is breaking the accessibility of the newList[] object. I've tried it a few ways, and it works if I'm inside the .each() iterator. But I need to access it outside.
Because Array indices are 0 based, this:
i = newList.length;
should be this:
i = newList.length - 1;
Otherwise the starting index is out of bounds, so newList[i] will be undefined, and accessing a property on undefined is a TypeError.
Once you correct that, you probably want to access a property defined on the object, like .value or .price, otherwise it will log undefined for each iteration.
Shouldn't this:
i = newList.length;
while (i > 0) {
console.log(newList[i].listItem);
i--;
}
Be this?
i = newList.length-1; // start on the last index, not length
while (i > 0) {
console.log(newList[i].value); // value, like in your top example
i--;
}