Concat multiple arrays into one array without duplicates [duplicate] - javascript

This question already has answers here:
Get all unique values in a JavaScript array (remove duplicates)
(91 answers)
Closed 6 years ago.
I want to push values of 3 arrays in a new array without repeating the same values
var a = ["1", "2", "3"];
var b = ["3", "4", "5"];
var c = ["4", "5", "6"];
var d = [];
function newArray(x, y, z) {
for(var i = 0; i < d.length; i++) {
if(d.length == -1) {
d[i].push(a[i])
}
}
for(var i = 0; i < d.length; i++) {
if(d.length == -1) {
d[i].push(y[i])
}
}
for(var i = 0; i < d.length; i++) {
if(d.length == -1) {
d[i].push(z[i])
}
}
}
newArray(a, b, c);
d = ["1", "2", "3", "4", "5", "6"];

You can use concat() and Set together as below,
var a = ["1","2","3"];
var b = ["3","4","5"];
var c = ["4","5","6"];
var d = a.concat(b).concat(c);
var set = new Set(d);
d = Array.from(set);
console.log(d);

If your goal is to remove duplicates, you can use a set,
var arr = [1, 2, 3, 4, 5, 5, 6, 6, 6, 7]
var mySet = new Set(arr)
var filteredArray = Array.from(mySet)
console.log(filteredArray.sort()) // [1,2,3,4,5,6,7]

var a = ["1","2","3"]
, b = ["3","4","5"]
, c = ["4","5","6"]
, d = [];
function newArray(x,y,z) {
x.concat(y,z).forEach(item =>{
if (d.indexOf(item) == -1)
d.push(item);
});
return d;
}
console.log(newArray(a,b,c));

You could save yourself some time and effort with the very useful utility library Lodash.
The function you're looking for is Union
As stated by Lodash:
Creates an array of unique values, in order, from all given arrays
using SameValueZero for equality comparisons.
Example
_.union([2], [1, 2]);
// => [2, 1]

var a = ["1", "2", "3"];
var b = ["3", "4", "5"];
var c = ["4", "5", "6"];
var d = [];
var hash = [];
AddToHash(a);
AddToHash(b);
AddToHash(c);
function AddToHash(arr) {
for (var i = 0; i < arr.length; i++) {
if (!hash[arr[i]]) {
hash[arr[i]] = 1;
} else
hash[arr[i]] += 1;
}
}
for (var i = 0; i < hash.length; i++) {
d.push(i);
}
console.log(d);
Hope this helps

Here is another version:
var d = b.concat(c);
d.forEach(function(el) {
if (a.indexOf(el) === -1) {
a.push(el)
}
})
ES6 version:
let d = b.concat(c);
d.forEach(el => {
if (a.indexOf(el) === -1) {
a.push(el)
}
})

Related

JavaScript IndexOf with heterogeneous array [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
javascript indexOf function is not working with mix type of array. any other alternatives
var myArray = ["2","3",5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++){
if(myArray.indexOf(i) === -1)
{
found .push(i);
}
}
console.log(found)
output : [1, 2, 3, 4, 6, 7, 8, 9]
Expected output : [1,4,6, 7, 8, 9]
Why 5 is missing ?
console.log(5 === "5")
indexOf(5) isn't -1 because 5 and "5" are two different value ( indexOf uses strict equality ) MDN indexOf
console.log([5].indexOf(5))
console.log(["5"].indexOf(5))
How can i match both 5 or "5" ?
Check for both numeric and string value.
var myArray = ["2", "3", 5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++) {
if (myArray.indexOf(i) === -1 && myArray.indexOf(String(i)) === -1) {
found.push(i);
}
}
console.log(found)
var myArray = ["2","3",5]
var found = [];
var range = 10;
var tmpArr = myArray.map(function(elm) {
return elm.toString();
});
for (var i = 1; i < range; i++){
if(tmpArr.indexOf(i.toString()) === -1) {
found .push(i);
}
}
console.log(found);
For this kind of use case, like to check if a value exists in a collection, you could take a Set with numbers as values and check this values agains a set of wanted numbers.
Array#indexOf takes a strict comparison and returns the index only if the value has the same identity (Identity/strict equality operator ===).
var array = ["2", "3", 5],
values = new Set(array.map(Number)),
found = [],
range = 10,
v;
for (v = 1; v < range; v++) if (!values.has(v)) found.push(v);
console.log(found);
Check for both strings and numbers as
[5] and ["5"] are treated differently because their types are different. i.e String and Number
var myArray = ["2", "3", 5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++) {
if (myArray.indexOf(String(i)) === -1 && myArray.indexOf(i) === -1) {
found.push(i);
}
}
console.log(found)
Because myArray.indexOf(5) is 2 and not -1.
var myArray = ["2","3",5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++){
console.log(i);
if(myArray.indexOf(i) === -1){
found .push(i);
}
}
console.log(found)
More here.
Array#indexOf only does strict equality to find the value, so because "2" === 2 and "3" === 3 are both false, then myArray.indexOf(i) returns -1 for i having the value 2 or 3.
If you want to look through an array of mixed types for only one type, then it's probably easier to make the array only one type first:
var myArray = ["2", "3", 5]
var found = [];
var range = 10;
//convery all to numbers
myArray = myArray.map(Number);
for (var i = 1; i < range; i++) {
if (myArray.indexOf(i) === -1) {
found.push(i);
}
}
console.log(found);
Alternatively, if the array has to stay with mixed types, you can use .some to check for presence and supply logic that is independent of types:
var myArray = ["2", "3", 5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++) {
//lookup using loose equals
var inArray = myArray
.some(item => item == i);
if (!inArray) {
found.push(i);
}
}
console.log(found);
okay as you need you expected result as [1,4,6, 7, 8, 9]
then you have to make some changes in if condition.
why i will let you know first-run code snippet
var myArray = ["2","3",5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++){
if(myArray.indexOf(i) === -1 && myArray.indexOf(String(i)) === -1)
{
found.push(i);
}
}
console.log(found)
myArray.indexOf(i) === -1 as you added
why myArray.indexOf(String(i)) === -1 because you have heterogeneous data.
int and string type data.

JavaScript Split String into multiple Arrays

I have a comma separated string in JavaScript that I want to separate into mutiple arrays, for each column but I want to ignore the first couple of lines. So for instance I want to convert the following string,
let data = "test,data,\n,ignore,this,\n,A,B,C,\n,1,2,3,\n,1,2,3";
into arrays like the following.
["A", "1", "1"]
["B", "2", "2"]
["C", "3", "3"]
EDIT
Ths is my initial solution that I tried. Like it works but it's not really a nice solution:/
for (let i = 1; i < out.length; i++)
{
let arr = out[i].split(',');
if (i === 1)
{
for (let j = 0; j < columns; j++)
{
let col = "arr" + j;
console.log(col);
obj[col] = [arr[j]];
}
console.log(obj);
}
else
{
for (let j = 0; j < columns; j++)
{
let col = "arr" + j;
let val = arr[j];
if (j !== "")
{
obj[col].push(val);
}
}
}
}
I should point out that I eventually want to create a map of the letters to corresponding array of numbers and I won't know what the key value will be. So I'll be trying to get something like the following,
"A": ["1", "1"]
"B": ["2", "2"]
"C": ["3", "3"]
You could split by ',\n,' for getting lines and for the items split by comma. Then omit the first two arrays.
var data = "test,data,\n,ignore,this,\n,A,B,C,\n,1,2,3,\n,1,2,3",
result = data.split(',\n,').map(s => s.split(',')).slice(2);
console.log(result);
for your expected result you first have to split a string by ',' and then run for loop on a resulted array and inside that convert, you alphabet with a number and compare numbers if match found than push it into a respective array.
like below code
var datArray= [];
a = [];
b = [];
c = [];
let data = "test,data,\n,ignore,this,\n,A,B,C,\n,1,2,3,\n,1,2,3";
datArray = data.split(',');
for(var i = 0; i < datArray.length; i++) {
if(datArray[i] == 'A' || datArray[i] == 1) {
a.push(datArray[i]);
} else if(datArray[i] == 'B' || datArray[i] == 2) {
b.push(datArray[i]);
} else if(datArray[i] == 'C' || datArray[i] == 3) {
c.push(datArray[i]);
}
}
console.log(a);
console.log(b);
console.log(c);
this is one of the way you can do...
This method is not hard coded ! With this method you can handle :
ABCDEF.... , 1 2 3 4 5 6 ...
We will split for first action. Then detect Not A Number function isNaN to detect A B C .
Array helpers :
var notNumber = [];
var numbers = [];
to store data .
On the end generate your results arrays !
Try this :
var data = "test,data,\n,ignore,this,\n,A,B,C,\n,1,2,3,\n,1,2,3";
var handler = data.split(",");
var preventFlag = true;
var countNaN = 0;
var notNumber = [];
var numbers = [];
//console.log(handler);
for (var x = 0;x < handler.length;x++) {
var currentData = handler[x];
if (preventFlag == false) {
if ( isNaN(currentData) ) {
notNumber.push(currentData);
}
else {
if (currentData != "\n") {
numbers.push(currentData);
}
}
}
if (currentData == "this"){
preventFlag = false;
}
}
//console.log(notNumber)
//console.log(numbers)
for (var z = 0; z < notNumber.length;z++) {
window["result" + z] = [];
window["result" + z].push(notNumber[z]);
//console.log(window["result0"])
window["result" + z].push(numbers[z])
window["result" + z].push(numbers[z + (notNumber.length) ])
}
// GENERATE RESULT ARRAY
console.log(window["result0"]);
console.log(window["result1"]);
console.log(window["result2"]);
//["A", "1", "1"]
//["B", "2", "2"]
//["C", "3", "3"]

loop minute in javascript

I have code like this:
var hour = 7;
for (var i = 0;i <= 1; i++ ){
var minute = 0;
console.log((i + hour) % 24);
}
when I run it, I get result like this:
7
8
my question: how to add the value in format minute ex: 0-59
so I wanna loop the data like this:
7:0
7:1
7:2
s.d
7:59
8:0
You could use a new array to store all your unique values. You will need to look into the new "uniques" array, if the value alreay exists and then use the default value:
var number= ["1", "2", "3", "4", "5", "6", "6"];
var default = 0;
var uniques = [];
var result = [];
for(var i=0; i < number.length; i++) {
if(!inArray(number[i], uniques) {
uniques.push(number[i]);
result.push(number[i]);
console.log(number[i]);
} else {
console.log(default);
result.push(default);
}
}
function inArray(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
You could use Array#indexOf and check against the actual index. If you get the same index, then show the element, otherwise use a default value instead.
var number= ["1", "2", "3", "4", "5", "6", "6"];
for (var i = 0; i < number.length;i++) {
console.log(number.indexOf(number[i]) === i ? number[i] : undefined);
}
Use map to get the new array, and in the callback store each item in a set to know if it's a duplicate or not.
var number = ["1", "2", "3", "4", "5", "6", "6"];
var s = new Set();
console.log(number.map(n => s.has(n) ? undefined : s.add(n) && n));
If the non-equality of your values is respected by stringification, you can use a plain object, without needing ES6 features:
var number = ["1", "2", "3", "4", "5", "6", "6"];
var s = Object.create(null);
console.log(number.map(function(n) {
if (n in s) return undefined;
s[n] = true;
return n;
}));

find number of string matches from array to array in javascript?

I need to find number of strings in array b that contains in array arr. I got the output but i need it in this order.[[3,6,0],[1,3,1]]
here my code goes.
var arr = [["00","00","00","01","01","01","01","01","01"],["000","100","01","01","01"]];
var b = ["00","01",10];
var cc = [];
for (var i=0;i<b.length;i++) {
var k = [];
for (var y=0;y<arr.length;y++) {
var a = 0;
for (var x=0;x<arr[y].length;x++) {
if ((arr[y][x].substring(0,2)).indexOf(b[i]) != -1) {
a++;
}
}
k.push(a)
}
cc.push(k);
}
console.log(JSON.stringify(cc));// output :[[3,1],[6,3],[0,1]]
Actual output : [[3,1],[6,3],[0,1]]
Expected output : [[3,6,0],[1,3,1]]
I want the result either in javascript or jquery.
As you have in b number 10 you need convert it to String and then search in array, because arr contains only strings
var arr = [
["00","00","00","01","01","01","01","01","01"],
["000","100","01","01","01"]
];
var b = ["00", "01", 10];
var len, i, j, key, result = [], counts = [], count = 0;
for (i = 0, len = arr.length; i < len; i++) {
for (j = 0; j < b.length; j++) {
count = 0;
key = String(b[j]);
count = arr[i].filter(function (el) {
return el.slice(0, 2) === key;
}).length;
counts.push(count);
}
result.push(counts);
counts = [];
}
console.log(JSON.stringify(result));
Version for IE < 9, where there is not .filter method
var arr = [
["00","00","00","01","01","01","01","01","01"],
["000","100","01","01","01"]
];
var b = ["00", "01", 10];
var len,
key,
result = [],
counts = [],
i, j, k, count;
for (i = 0, len = arr.length; i < len; i++) {
for (j = 0; j < b.length; j++) {
count = 0;
key = String(b[j]);
for (k = 0; k < arr[i].length; k++) {
if (arr[i][k].slice(0, 2) === key) {
count++;
}
}
counts.push(count);
}
result.push(counts);
counts = [];
}
console.log(JSON.stringify(result));
Seems like there are some typo in your sample input. Following code may help.
var arr = [["00","00","00","01","01","01","01","01","01"],["00","10","01","01","01"]];
var b = ["00","01","10"];
var cc = [];
arr.forEach(function(ar,i){
cc[i] = [];
b.forEach(function(a,j){
cc[i][j] = ar.filter(function(d){ return d==a }).length;
});
});
alert(JSON.stringify(cc));
Or
var arr = [
["00", "00", "00", "01", "01", "01", "01", "01", "01"],
["00", "10", "01", "01", "01"]
];
var b = ["00", "01", "10"];
var cc = arr.map(function(ar) {
return b.map(function(a) {
return ar.filter(function(d) {
return d == a
}).length;
})
});
alert(JSON.stringify(cc));

removing duplicate numbers out of both arrays

I know that you can remove 1 of the duplicate number out of an array but is there a way you can remove the number if they're duplicate? So far, below code is what I have. I wanted to use for loop to remove the number out of the array if they're equal, but I dont think I coded it correctly or it's not complete. I want it to return [3, 4, 5]
function sym(args) {
var array = [];
var join;
for(var i = 0; i < arguments.length; i++){
array.push(arguments[i]);
join = array[0].concat(array[1]);
}
join.sort();
for(var j = 0; j < join.length; j++) {
if(join[j] === join[j+1]) {
var removed = join.splice(j, join[j+2]);
console.log(removed);
}
}
return join;
}
sym([1, 2, 3], [5, 2, 1, 4]);
Here's my take
function sym() {
var vals = {};
var rarray= [];
var a=arguments;
for (var i=0,l=a.length;i<l;i++) {
if (a[i] instanceof Array) {
for (var n=0,ln=a[i].length;n<ln;n++) {
vals[a[i][n]]=vals[a[i][n]]||[];
vals[a[i][n]].push(a[i][n]);
}
}
}
for (var i in vals) {
if (vals.hasOwnProperty(i)) {
if (vals[i].length===1)
rarray.push(i);
}
}
return rarray;
}
Examples:
sym([1, 2, 3], [5, 2, 1, 4]);
// return: ["3", "4", "5"]
sym([1, 2, 3], [5, 2, 1, 4],[4,6,7,8],[8,4]);
// ["3", "5", "6", "7"]
sym([1,2],[1]);
// return: ["2"]
var sym = function (ar1, ar2) {
return ar1
.concat(ar2)
.sort(function (a, b) { return a - b; })
.filter(function (elem, i, ar) {
return ar[i-1] !== elem && ar[i+1] !== elem;
});
}
I like Crayon Violent's solution, but I don't see the point in maintaining arrays of duplicate items when you can simply count them.
This provides a large performance increase (jsperf), while also simplifying the code.
function sym() {
var occurrences = {};
var inputArrays = arguments;
var uniqueItems = [];
function addOccurrences(arr) {
for (var i = 0, len=arr.length; i < len; i++) {
occurrences[arr[i]] = 1 + (occurrences[arr[i]] || 0);
}
}
for (var i=0, len=inputArrays.length; i < len; i++) {
if (inputArrays[i] instanceof Array) {
addOccurrences(inputArrays[i]);
}
}
for (var item in occurrences) {
if (occurrences[item] === 1) {
uniqueItems.push(item);
}
}
return uniqueItems;
}
Which can be made nicer if you happen to have underscore or lodash in your project:
function sym() {
var inputArrays = _.filter(arguments, _.isArray);
var occurrences = {};
function addOccurrences(arr) {
_.forEach(arr, function(item){
occurrences[item] = 1 + (occurrences[item] || 0);
});
}
_.forEach(inputArrays, addOccurrences);
// Select the items with one occurence, return the keys (items)
return _.filter(_.keys(occurrences), function(item){
return occurrences[item] === 1;
});
}

Categories