I have a few arrays I want to union, but I need to keep them in order.
Example:
var js_files = [
'bower_components/jquery/dist/jquery.js',
'bower_components/jquery.cookie/jquery.cookie.js',
'bower_components/jquery-placeholder/jquery-placeholder.js',
'bower_components/foundation-sites/dist/foundation.js',
'bower_components/Swiper/dist/js/swiper.jquery.min.js',
'assets/scripts/**/*.js'
];
and:
var js_files = [
'bower_components/jquery/dist/jquery.js',
'parnet/bower_components/jquery/dist/jquery.js',
'parent/bower_components/jquery.cookie/jquery.cookie.js'
];
and I want union them and make sure the fist array will stay first & remove duplicate values.
expected outotput:
['bower_components/jquery/dist/jquery.js',
'bower_components/jquery.cookie/jquery.cookie.js',
'bower_components/jquery-placeholder/jquery-placeholder.js',
'bower_components/foundation-sites/dist/foundation.js',
'bower_components/Swiper/dist/js/swiper.jquery.min.js',
'assets/scripts/**/*.js',
'parnet/bower_components/jquery/dist/jquery.js',
'parent/bower_components/jquery.cookie/jquery.cookie.js']
Can I do this using _.union? Any other idea?
You could use Set in combination with the spread syntax ... for unique items in original sort order.
var js_files1 = [
'abc',
'def',
'bower_components/jquery/dist/jquery.js',
'bower_components/jquery.cookie/jquery.cookie.js',
'bower_components/jquery-placeholder/jquery-placeholder.js',
'bower_components/foundation-sites/dist/foundation.js',
'bower_components/Swiper/dist/js/swiper.jquery.min.js',
'assets/scripts/**/*.js'
],
js_files2 = [
'def',
'ghi',
'bower_components/jquery/dist/jquery.js',
'parnet/bower_components/jquery/dist/jquery.js',
'parent/bower_components/jquery.cookie/jquery.cookie.js'
],
uniqueFiles = [...new Set([...js_files1, ...js_files2])];
console.log(uniqueFiles);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do this in the ES5 fashion using Array.prototype.slice eg :
const first = [1,2,3,4];
const second = [5,6,7,8];
const results = [].concat(first.slice(), second.slice());
Or the ESNext fashion using "desctructuring"
const first = [1,2,3,4];
const second = [5,6,7,8];
const result = [...first, ...second];
Edit : I missed the point that you need distinct values;
This will remove dupes from results after you concatenated stuff.
const distinctResults = results.filter(function removeDuplicates(item, index){
return results.indexOf(item) === index;
});
var a = [1,2,3];
var b = [4,5,6];
var Joined = [...a,...b];
Similarly can do for your code.
just use Array.prototype.concat
var js_files1 = [
'bower_components/jquery/dist/jquery.js',
'bower_components/jquery.cookie/jquery.cookie.js',
'bower_components/jquery-placeholder/jquery-placeholder.js',
'bower_components/foundation-sites/dist/foundation.js',
'bower_components/Swiper/dist/js/swiper.jquery.min.js',
'assets/scripts/**/*.js'
];
var js_files2 = [
'parnet/bower_components/jquery/dist/jquery.js',
'parent/bower_components/jquery.cookie/jquery.cookie.js'
];
var res = js_files1.concat(js_files2);
console.log(res);
var js_files1 = [
'bower_components/jquery/dist/jquery.js',
'bower_components/jquery.cookie/jquery.cookie.js',
'bower_components/jquery-placeholder/jquery-placeholder.js',
'bower_components/foundation-sites/dist/foundation.js',
'bower_components/Swiper/dist/js/swiper.jquery.min.js',
'assets/scripts/**/*.js'
];
var js_files2 = [
'parnet/bower_components/jquery/dist/jquery.js',
'parent/bower_components/jquery.cookie/jquery.cookie.js',
"assets/scripts/**/*.js"
];
js_files2.forEach(value => {
if (js_files1.indexOf(value) == -1) {
js_files1.push(value);
}
});
console.log(js_files1);
_.union will remove duplicate values from your second array.
In your case you dont have any duplicate value in second array so it will simply concat them
But if you have any duplicate value in second array, _.union will remove it
for eg.
var a = [
'bower_components/jquery/dist/jquery.js',
'bower_components/jquery.cookie/jquery.cookie.js',
'bower_components/jquery-placeholder/jquery-placeholder.js',
'bower_components/foundation-sites/dist/foundation.js',
'bower_components/Swiper/dist/js/swiper.jquery.min.js',
'assets/scripts/**/*.js'
];
var b = [
'bower_components/jquery/dist/jquery.js',
'parnet/bower_components/jquery/dist/jquery.js',
'parent/bower_components/jquery.cookie/jquery.cookie.js'
];
_.union(a, b) will result in
[
"bower_components/jquery/dist/jquery.js",
"bower_components/jquery.cookie/jquery.cookie.js",
"bower_components/jquery-placeholder/jquery-placeholder.js",
"bower_components/foundation-sites/dist/foundation.js",
"bower_components/Swiper/dist/js/swiper.jquery.min.js",
"assets/scripts/**/*.js",
"parnet/bower_components/jquery/dist/jquery.js",
"parent/bower_components/jquery.cookie/jquery.cookie.js"
]
Here you can see _.union removes duplicate value "bower_components/jquery/dist/jquery.js" of array B in the result
Related
We have same two arrays to groupby theme by index.
Two arrays with same length and different value like blow.
How to groupby two array with their index by ES6 reduce or lodash?
array1 = [1,2,3,4] OR [{a:1},{b:2},{c:3},{d:4}]
array2 = [5,6,7,8] OR [{e:5},{f:6},{g:7},{h:8}]
finalArray = [[1,5],[2,6],[3,7],[4,8]]
I'm trying with different ways like group by with reduce in es6 or lodash concat but i can't find best solution for my problems.
Try this:
let array1 = [1, 2, 3, 4];
let array2 = [5, 6, 7, 8];
let res = array1.map((value, index) => {
return [value, array2[index]]
})
console.log(res);
If it is array of objects
let array1 = [{a:1},{b:2},{c:3},{d:4}];
let array2 = [{e:5},{f:6},{g:7},{h:8}];
let res = array1.map((value, index) => {
return [Object.values(value)[0],Object.values(array2[index])[0]]
})
console.log(res)
Use lodashes zip function
// _ is lodash
const array1 = [1,2,3,4]
const array2 = [5,6,7,8]
console.log(_.zip(array1, array2))
result
[ [ 1, 5 ], [ 2, 6 ], [ 3, 7 ], [ 4, 8 ] ]
If you are working with the array of objects. Get just the values using Object.values and grab the 0th element.
const array3 = [{a:1},{b:2},{c:3},{d:4}];
const array4 = [{e:5},{f:6},{g:7},{h:8}];
function firstval(ob){
return Object.values(ob)[0]
}
console.log(_.zip(array3.map(firstval), array4.map(firstval)))
You can also write your own zip. This is a limited version. That handles only 2 elements, doesn't accept or return generators etc.
It could easily be extended to take a spread operator and therefore any number of arguments. You don't seem to need that level of flexibility though.
function zip(a, b) {
const num = Math.min(a.length, b.length);
const result = [];
for(i = 0; i < num; i++) result.push([a[i], b[i]]);
return result;
}
Following code works under these assumptions:
all input arrays have same length
if array element is object, it has only one property
function getValue(element) {
if (typeof element === 'object') {
return Object.values(element).pop()
} else {
return element
}
}
function zipArrays(arr1, arr2) {
return arr1.reduce((acc, elm1, index) => {
const elm2 = arr2[index]
const elm = [getValue(elm1), getValue(elm2)]
acc.push(elm)
return acc
}, [])
}
// usage:
const array1 = [1,2,3,4] // OR [{a:1},{b:2},{c:3},{d:4}]
const array2 = [5,6,7,8] // OR [{e:5},{f:6},{g:7},{h:8}]
const finalArray = zipArrays(array1, array2)
I have the following array:
var array= [
'http://www.example.com/page1/#comment-1234',
'http://www.example.com/page1/#comment-98733',
'http://www.example.com/page1/#comment-4298312',
'http://www.example.com/page2/#comment-2143'
]
I would like to distinct this array to return just with:
//['http://www.example.com/page1','http://www.example.com/page2']
How would I do this with JS?
Appreciate the help!
slice the base url and then use includes.
var array = [
'http://www.example.com/page1/#comment-1234',
'http://www.example.com/page1/#comment-98733',
'http://www.example.com/page1/#comment-4298312',
'http://www.example.com/page2/#comment-2143'
];
const output = [];
array.forEach((url) => {
const base = url.slice(0, 28);
if (!output.includes(base)) output.push(base);
});
console.log(output);
-- Edit--
var array = [
'http://www.example.com/page1/#comment-1234',
'http://www.example.com/page123/#comment-98733',
'http://www.example.com/page1/#comment-4298312',
'http://www.example.com/page2/#comment-2143'
];
const output = [];
array.forEach((url) => {
const idx = url.lastIndexOf('/');
const base = url.slice(0, idx);
if (!output.includes(base)) output.push(base);
});
console.log(output);
You should use reduce method of array in javascript, like this
var array = [
'http://www.example.com/page1/#comment-1234',
'http://www.example.com/page1/#comment-98733',
'http://www.example.com/page1/#comment-4298312',
'http://www.example.com/page2/#comment-2143'
]
const newArr = array.reduce((newArray, value) => {
const url = value.replace(/\/#.*$/, "")
if (newArray.indexOf(url) === -1) {
newArray.push(url)
}
return newArray;
}, []);
console.log(newArr)
You can use new Set() to get rid of duplicate elements in an array.
First step, create an array consisting of the URLs without the hashbangs. I'm using split for this.
const URLs = array.map(URL => URL.split('/#')[0]);
You can remove duplicates from that by passing it into a set, then spreading the result back into an array.
const uniques = [...new Set(URLs)];
Lastly, if you want a more robust method to get the part before the hashbang (e.g. if some URLs contain https), look into using URL. https://developer.mozilla.org/en-US/docs/Web/API/URL
const array= [
'http://www.example.com/page1/#comment-1234',
'http://www.example.com/page1/#comment-98733',
'http://www.example.com/page1/#comment-4298312',
'http://www.example.com/page2/#comment-2143'
];
const URLs = array.map(URL => URL.split('/#')[0]);
const uniques = [...new Set(URLs)];
console.log(uniques);
var array= [
'http://www.example.com/page1/#comment-1234',
'http://www.example.com/page1/#comment-98733',
'http://www.example.com/page1/#comment-4298312',
'http://www.example.com/page2/#comment-2143'
];
var results = array.map(function(url){
var index = url.indexOf("#");
return url.substr(0, index);
});
var disctinctResult = [...new Set(results)]
You can use URL objects to remove the hashes and then, filter out the duplicates. Here is an example:
const array = [
'http://www.example.com/page1/#comment-1234',
'http://www.example.com/page1/#comment-98733',
'http://www.example.com/page1/#comment-4298312',
'http://www.example.com/page2/#comment-2143'
];
const result = array.map(str => {
const url = new URL(str);
return `${url.origin}${url.pathname}`
}).filter((urlStr, index, arr) => arr.indexOf(urlStr) !== index);
console.log(result);
So, you can also use regular expressions, to remove unwanted part of string.
var array= [
'http://www.example.com/page1/#comment-1234',
'http://www.example.com/page1/#comment-98733',
'http://www.example.com/page1/#comment-4298312',
'http://www.example.com/page2/#comment-2143'
]
const mapped = array.map(item => item.replace(/\/\#comment-[0-9]{0,}/, ''))
console.log(mapped);
// ["http://www.example.com/page1", "http://www.example.com/page1",
// "http://www.example.com/page1", "http://www.example.com/page2"]
My data is animalCount: {Tiger: 3, Leopard: 6, Rat: 1}
So I need to have 1st array
name :['Tiger', 'Leopard', 'Rat']
2nd array
count: [3, 6, 1]
Is it possible to obtain the same?
Sure, just use:
const names = Object.keys(animalCount);
const values = Object.values(animalCount);
As others have mentioned, you can use:
var name = Object.keys(animalCount);
var count = Object.values(animalCount);
If you, for some reason, needed to manipulate or change them while creating these arrays, you could also use a for i in animalCount loop, like so:
var animalCount = {Tiger: 3, Leopard: 6, Rat: 1};
var array1 = [];
var array2 = [];
for(i in animalCount){
if(animalCount.hasOwnProperty(i)){
array1.push(i);
array2.push(animalCount[i]);
}
}
console.log(array1);
console.log(array2);
How about
var name = [];
var count = [];
for(var prop in animalCount){
name.push(prop);
count.push(animalCount[prop]);
}
This way we're sure the order is preserved.
JS supports this natively.
var name = Object.keys(animalCount);
var count = Object.values(animalCount);
See:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys for Object.keys and
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values for Object.values
You could take a single loop and reduce the entries of the object by iterating the key/value array for pushing the items.
var animalCount = { Tiger: 3, Leopard: 6, Rat: 1 },
names = [],
count = [],
result = Object
.entries(animalCount)
.reduce((r, a) => (a.forEach((v, i) => r[i].push(v)), r), [names, count]);
console.log(names);
console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have two arrays something like this.
array1 = [{name:'arjun', place:'mysore'},{name:'kanka', place:'bangalore'}];
array2 = [{name: 'arjun', degree:'BE'},{name:'kanka', degree:'MCA'}]
The result Should be Something like this.
array3 = [{name: 'arjun', place:'mysore', degree:'BE'}, {name:'kanka',place:'bangalore',degree:'MCA'}];
The above result Array doesn't have duplicate values now. Can anyone help please?
Assuming that you need to merge arrays by index and are of same length.
let array1 = [{name:'arjun', place:'mysore'},{name:'kanka', place:'bangalore'}];
let array2 = [{name: 'arjun', degree:'BE'},{name:'kanka', degree:'MCA'}]
let array3 = array1.map((o,i) => ({...o, ...array2[i]}));
console.log(array3);
You can simply use a Array.map() and Object.assign()
array1 = [{name:'arjun', place:'mysore'},{name:'kanka', place:'bangalore'}];
array2 = [{name: 'arjun', degree:'BE'},{name:'kanka', degree:'MCA'}];
let result = array1.map((a)=>{
let obj2 = array2.find((b)=> a.name === b.name);
if(obj2)
Object.assign(a,obj2);
return a;
});
console.log(result);
I think you can use array#reduce to do something like this perhaps:
array1 = [{name:'arjun', place:'mysore'},{name:'kanka', place:'bangalore'}];
array2 = [{name: 'arjun', degree:'BE'},{name:'kanka', degree:'MCA'}]
var resultArray = array1.reduce((arr, e) => {
arr.push(Object.assign({}, e, array2.find(a => a.name == e.name)))
return arr;
}, [])
console.log(resultArray);
NOTE: It will also work if those arrays are of different length.
use the foreach like this
let array1 = [{name:'arjun', place:'mysore'},{name:'kanka', place:'bangalore'}];
let array2 = [{name: 'arjun', degree:'BE'},{name:'kanka', degree:'MCA'}]
let array3 = [];
array1.forEach((item, index) => {
array3.push(item)
let degree = array2.find(e => e.name === item.name)
if(degree){
array3[index].degree = degree.degree
}
})
console.log(array3)
If both arrays are of the same length then this solution will work.
array1 = [{name:'arjun', place:'mysore'},{name:'kanka', place:'bangalore'}];
array2 = [{name: 'arjun', degree:'BE'},{name:'kanka', degree:'MCA'}]
const array3 = [];
for(let i=0; i < array1.length; i++){
array3.push(Object.assign(array1[i], array2[i]));
}
console.log(array3);
Working JSBin here.
Look here also: How can I merge properties of two JavaScript objects dynamically?
You can make an aggregation of properties by the name with reduce and map out the aggregated data to an array:
const array1 = [{name:'arjun', place:'mysore'},{name:'kanka', place:'bangalore'}];
const array2 = [{name: 'arjun', degree:'BE'},{name:'kanka', degree:'MCA'}];
const objData = [...array1, ...array2].reduce((all, { name, place, degree }) => {
if (!all.hasOwnProperty(name)) all[name] = { name };
if (place) all[name].place = place;
if (degree) all[name].degree = degree;
return all;
}, {});
const result = Object.keys(objData).map(k => objData[k]);
console.log(result);
I have the following JavaScript object -
var newArray = { "set1": [], "set2": [] };
I am trying to push new data in this like -
newArray.set1.push(newSet1);
newArray.set2.push(newSet2);
Where newSet1 and newSet2 is equal to -
[{"test1","test1"},{"test2","test2"}] & [{"test3","test3"},{"test4","test4"}]
However when this is getting pushed in it is creating additional square brackets with the end result looking like -
{ "set1": [[{"test1","test1"},{"test2","test2"}]], "set2": [[{"test3","test3"},{"test4","test4"}]] }
When I actually need -
{ "set1": [{"test1","test1"},{"test2","test2"}], "set2": [{"test3","test3"},{"test4","test4"}] }
I tried setting my newArray as blank like -
var newArray = { "set1": '', "set2": '' };
However this did not work. How can I adjust it to accept the sets without adding additional brackets?
Use .concat()
var newArray = { "set1": [], "set2": [] };
newArray.set1 = newArray.set1.concat(newSet1);
newArray.set2 = newArray.set2.concat(newSet2);
You should say
newArray.set1.push(newSet1[0]);
newArray.set1.push(newSet1[1]);
newArray.set2.push(newSet2[0]);
newArray.set2.push(newSet2[1]);
newArray.set1 = newSet1;
newArray.set2 = newSet2;
Use Like
var newArray = { "set1": [], "set2": [] };
var arr1 = new Array ("A", "B", "C");
var arr2 = new Array (1, 2, 3);
var multiArr = new Array (arr1, arr2);
// or
var multiArr = [arr1, arr2];
// or
var multiArr = [["A", "B", "C"], [1, 2, 3]];
// you can access the elements of the array by zero-based indices
var firstRow = multiArr[0]; // same as arr1
var secondRowFirstCell = multiArr[1][0]; // 1
newArray.set1.push(multiArr[0]); //so, you need to use this with
newArray.set1.push(multiArr[1]); //so, you need to use this with
console.log(newArray);
DEMO