I'm looking at an exercise and having trouble understand how the following works ( I'm trying to remove duplicates from an array)
var arr = ['a','b','c','a','b','d','e','f'];
var uniqueArray = arr.filter(function(item,pos){
return arr.indexOf(item) == pos;
});
My attempt to understand
Here item takes on all of our values in arr. Lets go through an iteration
First item = 'a' and pos = 0. Ok. now we want to only filter on the basis of if the index of 'a'is the same as 0
Here indexOf(a) == 0.
Great! this is true, lets put it in the new array.
Now lets move forward to where we see a again, namely at pos = 3
arr.indexOf(a) == 3
Wait... Doesent this meet our requirement as well? How does this even remove duplicates?
indexOf returns just one integer value, and it is the index of the first found item. So, when pos is 3 (and the item is a), indexOf will return 0 (because the first index of a is 0), 0==3 is false and the element will be removed.
Then, when the pos is 4 (and item is b), indexOf returns 2, the index of the first found b.
As for the objects, they can't have duplicate keys. Each new key will automatically overwrite the old one, so there won't be any duplicates.
Look:
var obj = {a:1, a:3, b:2,c:5,b:4};
console.log(obj)
nicael is right. indexOf(item) is just a function that goes through the array and looks for the first time item appears in the array, and returns the position in the array. In your example, if there is an a at 0 and a at index 3, then indexOf('a') will return position 0, while the value of pos is 3, so the filter returns false.
FOLLOW UP:
indexOf() has another parameter called the fromIndex, which lets you start the search from a position other than the beginning of the array. In this case, you can specify to skip over the first time 'a' occurs by doing arr.indexOf('a', 1) which starts the search at position 1, not 0. In this case the function would return true since the next 'a' is at position 3.
Can I use filter on an object?
No, because filter is a specific function of an Array object. You can get the keys of the object by doing a filter on Object.keys(myObject) since keys() returns an array.
Using your example:
var keyArray = Object.keys(myObject); //object can't have duplicate keys
keyArray.filter(function(item, index) {
return keyArray.indexOf(item) == index; //will never be false
});
Hashtable is the best way to eliminate the redundant values
Here is the code :
char arr[] = ['a','b','c','a','b','d','e','f'];
//it will contains all 26 places as zero (A - Z)
char hashArray[26]={0}
int i; //for iteration;
for(i=0;arr[i]!='\0';i++)
{
//it will subtracte the ascii value of the letter
//from 'a' so that we have the values from 0 to 26)
hashArray[arr[i]-'a']=arr[i];
}
for(i=0;i<26;i++)
{
if(hashArray[i]!=0) //to Ensure the positon has the character
{
printf("%c",hashArray[i]);
}
}
Related
var data = [1, 2, 3, 5, 2, 1, 4];
// iterate over elements and filter
var res = data.filter(function (v) {
// get the count of the current element in array
// and filter based on the count
return data.filter(function (v1) {
// compare with current element
return v1 == v;
// check length
}).length == 1;
});
console.log(res);
I understand all the line in this code, but I don't understand how it can detect the length==1.
(My opinion) Because it loop though every single element in the array and return boolean value either true or false so how it can use to detect the length?
This code is to get the array element that only appear once in the array.
The return true is not to return the boolean, but when you return true from inside a filter, that item gets added to the resulting array of filter function.
The process here is called chaining of methods. On line 11, first, the filter is applied to the data array, then the .length method is applied to the result of the filter, which will be an array of equal length or less than the number of elements in the data array. Then finally only once the return is called, which will be a boolean used for the outer filter.
Another example:
function reverseString (inputString) {
return inputString.split("").reverse().join()
}
In the above example, the function returns after the split, then reverse on the split's result, then join on the reverse's result. The final resulting string is only returned.
Don't think about it as lines of code. Split each segment of code into its true meaning my padawan
data.filter(function (v1) {
// compare with current element
return v1 == v;
// check length
})
filters the data array to return an array of elements from data such that every element in it is equal to v
By checking if its length is 1, you want to return true if the the array has only 1 element.
So,
var res = data.filter(function (v) {
// return true if there is only 1 element in data which is equal to v
});
Which basically means, we are filtering data, and returning a new array where every element is such that it has only one occurrence in the array.
The function for filter returns a boolean, but filter itself returns an array.
So, for example:
array.filter(function(element) { return element >= 0; });
says that the function function(element) { return element >= 0; } will be applied to each element in array. Then, if the result of the function is true, that element will exist in the final, filtered version of array (which is what the filter function returns), or will not exist if the result is false.
In effect, all negative numbers from array will be filtered out because they return false.
What your code is saying is the following: For every element in data, filter data to keep only the elements equal to the current one. If this filtered list has only one element, then it can only be our current element. Therefor this element exists only once and should be kept in the final result, so we return true if .length == 1. In the end, once this is done for every element, filter is smart enough to convert those results of true and false into an array of the elements that produced true and leave out those that produced a false.
I will describe the filter method step by step in detail.
First, it takes a condition. then it returns an array with all values which passed the condition successfully
so think about this block of code as a condition
return data.filter(function (v1) {
// compare with current element
return v1 == v;
// check length
}).length == 1;
so let's take the first part of the condition
data.filter(function (v1) {
// compare with current element
return v1 == v;
// check length
})
and let's say we gonna start with the first element 1 , so how many times v1 === v ? the answer is two times so it will return this array [1, 1]
so forget the condition we wrote in the first lines and think about it like that [1,1].length === 1.
So [1,1].length === 1 will return false
The same will happen with number 2. so let's talk about the number 3. it will be [3].length === 1 which is true which will go to the upper level and that's why the res will be finally [3, 5, 4]
I have the following function, which pretty much does what it supposed to, but I would like to understand exactly what it does on each steps of its loop.
Could you please take a look to the function below and give me a clear explanation commenting each step or the Filter and IndexOf methods?
Thank you very much in advance.
var arr = [6,2,6,8,9,9,9,4,5];
var unique = function(){
return arr.filter(function(e, i, a) {
return i === a.indexOf(e);
})
}
unique();
indexOf returns the first index of an element in an array:
[1,2,2,3].indexOf(2); // 1
So if you use filter as in your example when it gets to the second occurance of an element the index (i in your example) will not be equal to the value returned by indexOf and be dropped. In my array above the second 2 is at position 2 which obviously doesn't strictly equal the one returned by indexOf.
[1,2,2,3].filter((value, index, array) => array.indexOf(value) === index);
// first iteration: value is 1, index is 0, indexOf is 0 0===0 keep 1
// second: value is 2, index is 1, indexOf is 1, 1===1 keep 2
// third: value is 2, index is 2, indexOf is 1, 1===2 false! toss 2
// etc.
The end effect is that any duplicate elements get dropped from the copy returned by filter. And it is a copy, the original array is not mutated.
EDIT
I should probably mention that recent versions of JavaScript give us a better way:
let arrayWithDupes = [1,2,2,3];
let uniq = Array.from(new Set(arrayWithDupes)); // [1,2,3]
If log the values like:
var arr = [6,2,6,8,9,9,9,4,5];
var unique = function(){
return arr.filter(function(e, i, a) {
console.log('e: ' + e);
console.log('i: ' + i);
console.log('a: ' + a);
return i === a.indexOf(e);
})
}
var unq = unique();
console.log(unq);
you will get:
"e: 6"
"i: 0"
"a: 6,2,6,8,9,9,9,4,5"
and so on...
e = current element from array, i = index of the array, a = array source;
Filer function: "The filter() method creates an array filled with all array elements that pass a test (provided as a function)."
indexOf: "The indexOf() method searches the array for the specified item, and returns its position."
I have an array of objects and I am removing elements based on object value, without knowing which element it is.
So... those lovely people who flagged my question as duplicate and suggest I read How do I remove a particular element from an array in JavaScript? are not helping.
My question... again...
I have an array of objects
I want to search and remove specific elements from the array. I have a solution that is long winded (loop thru the array once, make a list of element id's, then slice one by one in another loop). I am hoping there is another method (enhance my skillset too).
myarray.filter(function(item)
{
if( item.flag==="Y" )
{
// how to delete element from myarray
// delete implies remove it from myarray
}
});
All help appreciated =)
You have at least two options:
Create a new array with filter
The first is to create a new array containing only the entries you want. You're already on the right track with filter:
myArray = myArray.filter(function(item) {
return item.flag !== "Y";
});
The new array will only have the entries that the callback returned a truthy value for. In this case, only ones whose flag is !== "Y". Entries whose flag is === "Y" will be left out of it.
Note that if you have other references to this same array in other variables, they will continue to point to the old array. Only myArray (in the above) gets a reference to the new array.
Modify the existing array with splice and a loop
The second is to use a while loop and splice:
var n = 0;
while (n < myArray.length) {
if (myArray[n].flag === "Y") {
// Remove it
myArray.splice(n, 1);
} else {
// Move to next
++n;
}
}
Note we don't move to next if we remove one, because we need to test the one after it (which is now at the previous index).
Or as Nina points out in a comment, a for loop going backward:
for (var n = myArray.length - 1; n >= 0; --n) {
if (myArray[n].flag === "Y") {
// Remove it
myArray.splice(n, 1);
}
}
In that case, since we're modifying the array (not creating a new one), the changes will be visible through any reference to that same array, not just myArray. (Since they all point to the same object, which we modified the state of.)
Remove object in array by its property-value:
Remove value: 30:
arr.splice(arr.map(el => el.value).indexOf(30), 1);
DEMO
Remove name: "John":
arr.splice(arr.map(el => el.name).indexOf("John"), 1);
I have an array like this:
var CutRoadArray = [
['Location', '_Location'],
['Applicant Info', '_ApplicantInfo'],
['Details', '_ApplicationDetails'],
['Bond Info', '_BondInfo'],
['Attachments', '_Attachments'],
['Review', '_ReviewA']
];
I am trying to replace the last item, with a different entry.
The code I have so far goes like below:
var newreviewElem = ['Review', '_ReviewB'];
var index = CutRoadArray.lastIndexOf('_ReviewA');
CutRoadArray.splice(index, 0, newreviewElem);
console.log(CutRoadArray);
This is however not working. What am I doing wrong ?
https://jsfiddle.net/yygLdo0o/
There are actually two things wrong with your answer.
The first is that you need to grab the correct index. If you're replacing the last item, just grab the array.length.
The second is that you need to indicate how many you're replacing:
CutRoadArray.splice(CutRoadArray.length - 1, 1, newreviewElem);
The second argument in splice should be 1, not 0.
This will replace the last element of any size array, because it doesn't rely on an item in the array being in a specific location or a particular index.
CutRoadArray.length - 1 is grabbing the number of items in the array, but since splice uses a zero based index, you have to subtract one to get the index of the last item in the array.
The second argument (bolded below), tells splice to replace a single item.
Documentation about splice
CutRoadArray.splice(CutRoadArray.length - 1, 1, newreviewElem);
And then finally, the last argument is the item to actually add to the array.
Working fiddle
It should be:
CutRoadArray.splice(index, 1, newreviewElem);
The second parameter indicates how many items should be replaced.
Your
CutRoadArray.lastIndexOf('_ReviewA');
will, of course, not find anything since CutRoadArray contains arrays, not strings.
for(var iter = 0; iter < CutRoadArray.length; iter++) {
if (CutRoadArray[iter][1] == '_ReviewA') {
CutRoadArray[iter] = newreviewElem;
break;
}
}
If you want to replace the element, use
CutRoadArray.splice(index, 1, newreviewElem);
The second parameter of splice is the deleteCount, 0 means no item will be removed.
An other problem with your code is that
CutRoadArray.lastIndexOf('_ReviewA');
will always return -1, as CutRoadArray is an array of arrays, meaning every element of it is an array, it doesn't have an element which is '_ReviewA'. (That's an element of one of CutRoadArray's elements.)
I suggest to iterate over the main array and search in the nested array for the wanted index. After found it is simple to replace the nested array at the index like array[index] = replace;. If not found, the the array is pushed to the end.
function replace(array, find, replace) {
var index;
if (array.some(function (a, i) {
if (~a.indexOf(find)) {
index = i;
return true;
}
})
) {
array[index] = replace;
} else {
array.push(replace);
}
}
var cutRoadArray = [
['Location', '_Location'],
['Applicant Info', '_ApplicantInfo'],
['Details', '_ApplicationDetails'],
['Bond Info', '_BondInfo'],
['Attachments', '_Attachments'],
['Review', '_ReviewA']
];
replace(cutRoadArray, '_ReviewA', ['Review', '_ReviewB']);
document.write('<pre>' + JSON.stringify(cutRoadArray, 0, 4) + '</pre>');
I have an array in javascript. I have to find last value of that array.
My code is like
var array= fruits;
and I have to find last fruit in that array.
Since in JavaScript arrays of size n are indexed from [0..n-1], you can get the last element by simply indexing the array at n-1, where is the length of the array and can be obtained by the .length property:
var lastFruit = array[array.length - 1];
If you want to get the last element and also remove it from the array, you can use the .pop methid:
var lastFruit = array.pop(); // get last element of array and remove it from array
Note: As RobG stated:
length is at least one more than the highest index, but might be
greater
First find number of elements in array and store it on variable like
var total = array.length;
Now you can find last value of array using below code
var last = array[total-1];
You accomplish this by using the length of the array (fruits.length) and subtracting 1 (because the array is 0 indexed). For instance...
fruits[0]="pear";
fruits[1]="apple";
fruits[2]="peach";
So fruits.length would be 3, so fruits.length - 1 = 2. So to get the last element...
var lastFruit = fruits[fruits.length-1];
I have to find last value of that array
The length property is at least one higher than the highest index, however it might be higher in which case the n-1 member may not exist. E.g.
// Create an array with length 10
var a = new Array(10);
// Add one member at index 0
a[0] = 'foo';
So the "last" value of the array is at index 0 and has a value of "foo". So you can start with length - 1 and search backwards for members that actually exist:
function lastValue(arr) {
var i = arr.length;
while (i--) {
if (i in arr) {
return arr[i];
}
}
// If get to here, arr has no members
return -1;
}
// All the following arrays have length 4 but different number of members
console.log(lastValue([ , , , ,])); // -1, i.e. there are no members
console.log(lastValue([0,1, , ,])); // 1
console.log(lastValue([0,1,2,3 ])); // 3
console.log(lastValue([ , , ,3 ])); // 3
If you know the Array only has numeric members (i.e. there are no non-numeric properties and no negative properties) you can do:
var arr = [,,'foo',,'bar',,]; // length 6, highest member is at index 4
console.log(arr[Math.max.apply(Math, Object.keys(arr))]); // 'bar'
Requires ES5 Object.keys.
Well you can find it's length then you know the last index, and can get the item from it
var last_item = array[array.length - 1];
Its as easy as:
fruits[fruits.length-1]