This question already has answers here:
Simplest code for array intersection in javascript
(40 answers)
Closed 8 years ago.
var array1 = [1, 2, 3, 4, 5, 6];
var array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
I have two arrays like above. Now I want to do the following in MVC 4 with jQuery.
If every elements of both arrays are equal then show a message/alert. e.g. "All records already existing."
If every elements of both the arrays are different then just add them all in a "VAR", e.g. var resultset = .... (where 7,8,9 will stored)
If few elements common between two arrays then for the common elements show a message with element, e.g. "Record 1,2,3,4,5,6 are already exists" and add the different elements in "VAR", e.g. var resultset = .... (where 7,8,9 will stored). Both the message and difference elements collection will perform at the same time.
Try this:
var array1 = [1, 2, 3, 4, 5, 6],
array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var common = $.grep(array1, function(element) {
return $.inArray(element, array2 ) !== -1;
});
console.log(common); // returns [1, 2, 3, 4, 5, 6];
var array3 = array2.filter(function(obj) { return array1.indexOf(obj) == -1; });
// returns [7,8,9];
Here is my version
function diff(arr1, arr2) {
var obj = {}, matched = [],
unmatched = [];
for (var i = 0, l = arr1.length; i < l; i++) {
obj[arr1[i]] = (obj[arr1[i]] || 0) + 1;
}
for (i = 0; i < arr2.length; i++) {
var val = arr2[i];
if (val in obj) {
matched.push(val);
} else {
unmatched.push(val);
}
}
// Here you can find how many times an element is repeating.
console.log(obj);
// Here you can find what are matching.
console.log(matched);
// Here you can check whether they are equal or not.
console.log('Both are equal ? :' +
matched.length === a.length);
// Here you can find what are different
console.log(unmatched);
}
If you do this kind of thing regularly, you may be interested in a Set object that makes this kind of stuff pretty easy:
var array1 = [1, 2, 3, 4, 5, 6];
var array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var common = new Set(array1).intersection(array2).keys();
The open source Set object (one simple source file) is here: https://github.com/jfriend00/Javascript-Set/blob/master/set.js
Along with the intersection() method used here, it has all sorts of other set operations (union, difference, subset, superset, add, remove ...).
Working demo: http://jsfiddle.net/jfriend00/5SCdD/
Related
This question already has answers here:
Reverse array in Javascript without mutating original array
(15 answers)
Closed 2 years ago.
I have been participating in some javaScript challenges and solved the reverse array challenge without modifying the original using the spread operator. I enjoy solving problems in different ways so i'm curious to find out from you. In what other way would you have solved it or would you solve it (excluding high order functions like map etc) ?
var newArray = [1,2,3,4,5,6];
const reverseArray = () => {
let arr = [...newArray];
for(let i = 0; i <= arr.length; i++){
arr.pop(i)
arr.unshift(i);
}
return arr
}
console.log(reverseArray())
You can use reverse();
var newArray = [1, 2, 3, 4, 5, 6];
var reverse = newArray.reverse();
console.log(reverse)
Use a for loop with increment to set index and then decrement value and push into array
var myArray = [1, 2, 3, 4, 5, 6, 7, 8];
function reverseArray(myArray) { // create a function and pass our array into it
var newArray = []; // define an empty array
for (var i = myArray.length - 1; i >= 0; i--) { // set for loop, declare a decrement for index as i - 1 to adjust for index, if greater than or equal to 0, decrement i
newArray.push(myArray[i]); // push the value into newArray
}
return newArray; // return newArray
}
console.log(reverseArray(myArray));
Use slice() reverse() and map() together index and value through function.
var myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var div = document.getElementById('div')
function sliceMap() {
reverseArray = myArray.slice(0).reverse().map(
function(value) {
return value;
}
);
div.innerHTML = reverseArray;
}
console.log(sliceMap())
<div id="div"></div>
Mapping values and then using unshift to reverse them.
var myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var reverseArray = [];
myArray.map((value) => {
reverseArray.unshift(value);
});
console.log(reverseArray)
I need to create a new array made up of unique elements from two separate arrays.
I have converted both arrays into a single array and then converted this into an object to check the frequency of the elements. If the value of an object property is 1 (making it a unique property), I want to return it to an array (minus the value). Is there a straightforward way to achieve this?
Edits: Moved result outside for loop. Expected output should be [4]
function diffArray(arr1, arr2) {
var finalArr = [];
var countObj = {};
var newArr = [...arr1, ...arr2];
for (var i = 0; i < newArr.length; i++) {
if (!countObj[newArr[i]]) countObj[newArr[i]] = 0;
++countObj[newArr[i]];
}
for (var key in countObj) {
if (countObj[key] === 1) {
finalArr.push(key);
}
} return finalArr;
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
If I understand correctly, you're wanting to find the difference between arr1 and arr2, and returns that difference (if any) as a new array of items (that are distinct in either array).
There are a number of ways this can be achieved. One approach is as follows:
function diffArray(arr1, arr2) {
const result = [];
const combination = [...arr1, ...arr2];
/* Obtain set of unique values from each array */
const set1 = new Set(arr1);
const set2 = new Set(arr2);
for(const item of combination) {
/* Iterate combined array, adding values to result that aren't
present in both arrays (ie exist in one or the other, "difference") */
if(!(set1.has(item) && set2.has(item))) {
result.push(item);
}
}
return result;
}
console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]), " should be [4]");
console.log(diffArray([1, 2, 3, 5, 8], [1, 2, 3, 5]), " should be [8]");
console.log(diffArray([1, 2, 3, 5, 8], [1, 2, 3, 5, 9]), " should be [8, 9]");
console.log(diffArray([1, 2], [1, 2]), " should be []");
How to sort randomly placed values in one array so that it matches the order provided by another array, but instead of appending the duplicates one after the other, the function should append the group of values, provided by the order variable, one after the other.
Input:
const array = [1, 5, 4, 3, 5, 3, 1, 5, 4];
const order = [5, 1, 3, 4];
Correct Output:
const correctlyOrderedArray = [5, 1, 3, 4, 5, 1, 3, 4, 5];
Wrong Output:
const wronglyOrderedArray = [5, 5, 5, 1, 1, 3, 3, 4, 4];
Two functions. The first one does the actual sorting and uses the second one inside itself.
Primary function:
function sortByOrder (array, order) {
const arrayOfArrays = order.map(v => {
return [...Array(howMany(v, array))].map(undef => v);
});
const tempArray = [];
arrayOfArrays.forEach((subArr, i) => {
let index = order.indexOf(order[i]);
subArr.forEach(duplicate => {
tempArray[index] = duplicate;
index += order.length;
});
});
return tempArray.filter(v => v);
}
Subordinate function:
function howMany(value, array) {
const regExp = new RegExp(value, 'g');
return (array.join(' ').match(regExp) || []).length;
}
If we suppose that the array order contains all the non duplicated elements of the array array, one way to achieve the sorting could be to copy the element of order using a modulo so that, we can restart the copy from the beginning.
const array = [1, 5, 4, 3, 5, 3, 1, 5, 4];
const order = [5, 1, 3, 4];
var newValue = []
for(var i = 0; i < array.length; i++){
newValue.push(order[i % order.length])
}
console.log(newValue)
We could iterate over the order and shift out elements out of our array until its empty:
const array = [1, 5, 4, 3, 5, 3, 1, 5, 4];
const order = [5, 1, 3, 4];
let i = 0, exit = false;
const result = [];
while(array.length){
const found = array.findIndex(el => el === order[i % order.length]);
if(found+1){
result.push( array.splice(found, 1)[0] );
exit = false;
}
if(i && i % order.length){
if(exit){
result.push(...array); //concat the rest
break;
}
exit = true;
}
i++;
}
The exit boolean will terminate the program if one order iteration did not found anything, e.g.:
const order = [1,2,3], array = [4,5,6,1,2,3,1,2,3];
Let it run!
When I want to remove one element, it is easy. This is my function:
function removeValues(array, value) {
for(var i=0; i<array.length; i++) {
if(array[i] == value) {
array.splice(i, 1);
break;
}
}
return array;
}
But how do I remove multiple elements?
Here a simple version using ES7:
// removing values
let items = [1, 2, 3, 4];
let valuesToRemove = [1, 3, 4]
items = items.filter((i) => !valuesToRemove.includes(i))
For a simple version for ES6
// removing values
let items =[1, 2, 3, 4];
let valuesToRemove = [1, 3, 4]
items = items.filter((i) => (valuesToRemove.indexOf(i) === -1))
const items = [0, 1, 2, 3, 4];
[1, 4, 3].reverse().forEach((index) => {
items.splice(index, 1)
})
// [0, 2, 4]
I believe you will find the kind of functionality you are looking for in Javascript's built in array functions... particularily Array.map(); and Array.filter();
//Array Filter
function isBigEnough(value) {
return value >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
//Array Map (Can also be used to filter)
var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
return num * 2;
});
// doubles is now [2, 8, 18]. numbers is still [1, 4, 9]
/////UPDATE REFLECTING REMOVAL OF VALUES USING ARRAY MAP
var a = [1,2,3,4,5,6];
a.map(function(v,i){
if(v%2==0){
a.pop(i);
}
});
console.log(a);
// as shown above all array functions can be used within the call back to filter the original array. Alternativelty another array could be populated within the function and then aassigned to the variable a effectivley reducing the array.
Here is the way I am using to return duplicate elements.. But I am facing most dangerous performance issues like browser close etc when my array have large number of items with long texts..
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var sorted_arr = arr.sort();
var results = [];
for (var i = 0; i < arr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
alert(results);
Please suggest me a best way of doing this
i don't get exactly what you want, but if you need to return duplicates you could use a cache object. this works with number or string or whatever.
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var cache = {};
var results = [];
for (var i = 0, len = arr.length; i < len; i++) {
if(cache[arr[i]] === true){
results.push(arr[i]);
}else{
cache[arr[i]] = true;
}
}
console.log(results);//returns an array with 9 and 4
Of course you can do other things like deleting multiple items etc. etc.
EDIT - i've written a blog entry on how to remove duplicates from an array
If you have array filter, you also have indexOf and lastIndexOf,
and you can return the duplicates without doing the sort.
var results, arr= [9, 9, 111, 2, 3, 4, 4, 5, 4, 7];
if(arr.filter){
results= arr.filter(function(itm, i){
return arr.lastIndexOf(itm)== i && arr.indexOf(itm)!= i;
});
}
else// use your loop method
alert(results)
/* returned value: (Array)
9,4
*/
Assuming Nicola's solution doesn't work for you (since it uses about as much memory as the original solution: two elements stored per element in the input, worst-case), you can use the slower process of repeatedly searching your input.
This requires the Array.indexOf method from ECMAScript 5. A lot of browsers have it. For alternatives, see How do I check if an array includes an object in JavaScript?.
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var results = [];
for (var i = 0, len = arr.length - 1; i < len; i++) {
if((results.indexOf(arr[i]) == -1) && (arr.indexOf(arr[i], i + 1) != -1)) {
results.push(arr[i]);
}
}
console.log(results);
This uses no more memory than the input arr plus the output results, but it's an O(N^2) algorithm and doesn't have to modify arr.
Your method relies on a sort, which may or may not be one reason you run out of space/time.
The canonical way to remove duplicates is to keep a hash map of the keys (an object in JS). The object keys you get back won't necessarily be in the order you want; you don't specify if you want the results ordered as well, but they are now.
You could null out the original array, since you no longer require it; when it gets collected is up to the JS engine though.
You could remove duplicates "in place" by keeping a "current index" into the sorted array, and increment it only when you move a non-duplicated element "down" from the counter index, then truncate the array that you return.
Combining the last two techniques should mean that in general you'll only have a single array with a valid reference.
Edit Example. Setting length explicitly, as .slice() creates a new array.
var have = {};
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
arr = arr.sort();
for (var rIdx = 0, i = 0; i < arr.length; i++) {
if (have[arr[i]]) {
arr[rIdx++] = arr[i];
} else {
have[arr[i]] = true;
}
}
arr.length = rIdx;
console.log(arr);