var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var point = 'c';
How can I split the "arr" into two arrays based on the "point" variable, like:
['a', 'b']
and
['d', 'e', 'f']
var arr2 = ['a', 'b', 'c', 'd', 'e', 'f'];
arr = arr2.splice(0, arr2.indexOf('c'));
To remove 'c' from arr2:
arr2.splice(0,1);
arr contains the first two elements and arr2 contains the last three.
This makes some assumptions (like arr2 will always contain the 'point' at first assignment), so add some correctness checking for border cases as necessary.
Use indexOf and slice
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var indexToSplit = arr.indexOf('c');
var first = arr.slice(0, indexToSplit);
var second = arr.slice(indexToSplit + 1);
console.log({first, second});
Sharing this convenience function that I ended up making after visiting this page.
function chunkArray(arr,n){
var chunkLength = Math.max(arr.length/n ,1);
var chunks = [];
for (var i = 0; i < n; i++) {
if(chunkLength*(i+1)<=arr.length)chunks.push(arr.slice(chunkLength*i, chunkLength*(i+1)));
}
return chunks;
}
Sample usage:
chunkArray([1,2,3,4,5,6],2);
//returns [[1,2,3],[4,5,6]]
chunkArray([1,2,3,4,5,6,7],2);
//returns [[1,2,3],[4,5,6,7]]
chunkArray([1,2,3,4,5,6],3);
//returns [[1,2],[3,4],[5,6]]
chunkArray([1,2,3,4,5,6,7,8],3);
//returns [[1,2],[3,4,5],[6,7,8]]
chunkArray([1,2,3,4,5,6,7,8],42);//over chunk
//returns [[1],[2],[3],[4],[5],[6],[7],[8]]
Try this one:
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var point = 'c';
var idx = arr.indexOf(point);
arr.slice(0, idx) // ["a", "b"]
arr.slice(idx + 1) // ["d", "e", "f"]
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var point = 'c';
Array.prototype.exists = function(search){
for (var i=0; i<this.length; i++) {
if (this[i] == search) return i;
}
return false;
}
if(i=arr.exists(point))
{
var neewArr=arr.splice(i);
neewArr.shift(0);
console.log(arr); // output: ["a", "b"]
console.log(neewArr); // output: ["d", "e", "f"]
}
Here is an example.
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var point = 'c';
var i = arr.indexOf(point);
var firstHalf, secondHalf, end, start;
if (i>0) {
firstHalf = arr.slice(0, i);
secondHalf = arr.slice(i + 1, arr.length);
}
//this should get you started. Can you think of what edge cases you should test for to fix?
//what happens when point is at the start or the end of the array?
When splitting the array you are going to want to create two new arrays that will include what you are splitting, for example arr1 and arr2. To populate this arrays you are going to want to do something like this:
var arr1, arr2; // new arrays
int position = 0; // start position of second array
for(int i = 0; i <= arr.length(); i++){
if(arr[i] = point){ //when it finds the variable it stops adding to first array
//starts adding to second array
for(int j = i+1; j <= arr.length; j++){
arr2[position] = arr[j];
position++; //because we want to add from beginning of array i used this variable
}
break;
}
// add to first array
else{
arr1[i] = arr[i];
}
}
There are different ways to do this! good luck!
Yet another suggestion:
var segments = arr.join( '' ).split( point ).map(function( part ) {
return part.split( '' );
});
now segments contains an array of arrays:
[["a", "b"], ["d", "e", "f"]]
and can get accessed like
segments[ 0 ]; // ["a", "b"]
segments[ 1 ]; // ["d", "e", "f"]
if you want to split into equal half; why no simple while loop ?
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var c=[];
while(arr.length > c.length){
c.push(arr.splice(arr.length-1)[0]);
}
Kaboom :).
Separate two arrays with given array elements as string array and number array;
let arr = [21,'hh',33,'kk',55,66,8898,'rtrt'];
arrStrNum = (arr) => {
let str = [],num = [];
for(let i = 0;i<arr.length;i++){
if(typeof arr[i] == "string"){
str.push(arr[i]);
}else if(typeof arr[i] == "number"){
num.push(arr[i]);
}
}
return [str, num]
}
let ans = arrStrNum(arr);
let str = ans[0];
let num = ans[1];
console.log(str);
console.log(num);
Related
Sorry if this is a duplicate or a dumb question!
Basically, I need to get the count for duplicate values in an array until the next value changes. I can't use reduce() in my project, so any plain JS would be helpful.
let array = [a,a,a,b,b,b,b,b,c,c,c,a,d,d];
Results:
a:3,
b:5,
c:3,
a:1,
d:2
I would appreciate it very much.
You can use regex to get the desired result.
/([a-z])\1*/gi
let array = ["a", "a", "a", "b", "b", "b", "b", "b", "c", "c", "c", "a", "d", "d"];
const result = array
.join("")
.match(/([a-z])\1*/gi)
.map((s) => `${s[0]}${s.length}`);
console.log(result);
Simply loop over chars and check if char in dict then increment it else set it to 1;
let chars = ['a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'a', 'd', 'd'];
const dic={}
for(char of chars){
if(char in dic){
dic[char]++;
}else{
dic[char]=1;
}
}
console.log(dic);//{a: 4, b: 5, c: 3, d: 2}
Run iteration over array elements. Find the next non-equal current character's position. then difference the two indexes you will find the current character's continuous last position. Increase the iteration so you need not worry about multiple counts. If no non-equal character found, then the size of the sub-array is the rest of the main array size.
let ara = ['a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'a', 'd', 'd'];
let index = 0;
for (var i = 0; i < ara.length; i++) {
let char = ara[i];
let size = 0;
let nextIndex = ara.findIndex(
(a, index) => a !== char && index > i);
if (nextIndex < 0) {
size = ara.length - i;
i = ara.length - 1;
} else {
size = nextIndex - i;
i = nextIndex - 1;
}
console.log(char + ' ' + size);
I'm coming from Python learning JavaScript. In Python, to find out if an item in one list is in another list, I can do something like:
haystack = ['a', 'b', 'c', 'd', 'e', 'f']
needle = ['a', 'b', 'e']
[i for i in haystack if i in needle]
In JavaScript, it seems the length of the list matters, as the code below returns ab rather than abe:
var needle = ["a", "b", "e"]
var haystack = ["a", "b", "c", "d", "e", "f"]
var found = "";
for (i=0; i < haystack.length; i++){
for (j=0; j < needle.length;j++){
if (needle[i] === haystack[j]) {
found+=needle[j]
}
}
}
console.log(found);
Python doesn't seem to care if the lists are of unequal lengths but JavaScript does. How can I do this in JavaScript?
You can do this
var needle = ["a", "b", "e"]
var haystack = ["a", "b", "c", "d", "e", "f"]
var list = needle.filter(word => haystack.indexOf(word) >= 0);
Here in this solution you don't have to iterate over length of the array explicitly. And it returns an array of filtered words.
Other choices
var list = needle.filter(word => haystack.includes(word));
The second one being not supported in IE.
You have done the indexing wrong
if (needle[i] === haystack[j])
will be
if (needle[j] === haystack[i])
And also instead of adding those strings into the array you have formed another string by concatenating them.
You've got the total right idea- the problem is that your if statement is backwards, so it's not iterating through each element in haystack.
if (haystack[i] === needle[j]) {
Length does not matter, you loop through both lists. You just made a little mistake on
if (needle[i] === haystack[j]) {
found+=needle[j]
}
Since you loop through haystack using i and needle using j. When you use haystack[j] instead of haystack[i] your if clause only goes up to "c" on haystack It should've been:
if (needle[j] === haystack[i]) {
found+=needle[j]
}
I would do this:
function inArray(v, a){
for(i=0,l=a.length; i<l; i++){
if(a[i] === v){
return true;
}
}
return false;
}
function needlesInHaystack(needlesArray, haystackArray){
for(var i=0,n,a=[],l=needlesArray.length; i<l; i++){
n = needlesArray[i];
if(inArray(n, haystackArray))a.push(n);
}
return a;
}
var needles = ['a', 'b', 'e', 'g'], haystack = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(needlesInHaystack(needles, haystack).join(''));
I'm trying to count duplicates in an array of dates and add them to a new array.
But i'm only getting the duplicates and the amount of times they exist in the array.
What I want is:
[a, a, b, c, c] => [a: 2, b: 1, c: 2]
Code:
$scope.result = { };
for(var i = 0; i < $scope.loginArray.length; ++i) {
if(! $scope.result[$scope.loginArray[i]]){
$scope.result[$scope.loginArray[i]] = 0;
++ $scope.result[$scope.loginArray[i]];}
}
Any suggestions?
You might need an object for this, not an array. So what you are doing is already great, but the if condition is messing up:
$scope.result = {};
for (var i = 0; i < $scope.loginArray.length; ++i) {
if (!$scope.result[$scope.loginArray[i]])
$scope.result[$scope.loginArray[i]] = 0;
++$scope.result[$scope.loginArray[i]];
}
Snippet
var a = ['a', 'a', 'b', 'c', 'c'];
var r = {};
for (var i = 0; i < a.length; ++i) {
if (!r[a[i]])
r[a[i]] = 0;
++r[a[i]];
}
console.log(r);
Or in better way, you can use .reduce like how others have given. A simple reduce function will be:
var a = ['a', 'a', 'b', 'c', 'c'];
var r = a.reduce(function(c, e) {
c[e] = (c[e] || 0) + 1;
return c;
}, {});
console.log(r);
For that, you can use .reduce:
var arr = ['a','a', 'b', 'c', 'c'];
var result = arr.reduce(function(p,c){
if(p[c] === undefined)
p[c] = 0;
p[c]++;
return p;
},{});
console.log(result);
You can use reduce and return object
var ar = ['a', 'a', 'b', 'c', 'c'];
var result = ar.reduce(function(r, e) {
r[e] = (r[e] || 0) + 1;
return r;
}, {});
console.log(result)
You can also first create Object and then use forEach add properties and increment values
var ar = ['a', 'a', 'b', 'c', 'c'], result = {}
ar.forEach(e => result[e] = (result[e] || 0)+1);
console.log(result)
lodash's countBy function will do the trick:
_.countBy(['a', 'a', 'b', 'c', 'c']) will evaluate to: {a: 2, b: 1, c: 2}
It does involve adding lodash as a dependency though.
I would do like this
var arr = ["a", "a", "b", "c", "c", "a"],
red = arr.reduce((p,c) => (p[c]++ || (p[c]=1),p),{});
console.log(red);
function chunk(arr, size) {
var newr = [];
var temp = [];
for (var i = 0; i < arr.length; i++) {
if (temp.length != size) {
temp.push(arr[i]);
} else {
newr.push(temp);
temp = [];
}
}
return newr;
}
chunk(['a', 'b', 'c', 'd'], 2);
Can someone help me why my code isn't working? It's just displaying the first chunk of array and ignoring the second.
Here is one efficient way of doing it using Array.splice():
function chunk(arr, size) {
var out = [];
while(arr.length) out.push(arr.splice(0, size));
return out;
}
Calling chunk(['a', 'b', 'c', 'd'], 2); will return:
[
["a", "b"],
["c", "d"]
]
Note: The above method will modify the original array that is passed into the function.
To fix your code, try this
function chunk(arr, size) {
var newr = [];
var temp = [];
for (var i = 0; i < arr.length; i++) {
temp.push(arr[i]);
if(temp.length==size || i==arr.length-1) {
newr.push(temp);
temp = [];
}
}
return newr;
}
chunk(['a', 'b', 'c', 'd'], 2); // results in [['a','b'],['c','d']]
chunk(['a', 'b', 'c', 'd', 'e'], 2); // results in [['a','b'],['c','d'],['e']]
Why your previous code doesn't work
Your condition works well. The last iteration does collect the last chunk ['c','d'] in temp correctly but it is not added to the newr list. Thus, a little modification to cover this issue is made in my code as shown above.
The question doesn't make much sense but not sure how to word it without an example. If someone can word it better, feel free to edit it.
Let's say I have an array of arrays such as this:
[ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ]
I would like the output to be:
['a', 'a', 'b', 'b', 'b', 'c', 'd', 'e']
Not sure if there is an easy way to do this in javascript/jquery/underscore. One way I could think of is to look through each of these arrays and count up the number of times each element shows up and keep track of the maximum amount of times it shows up. Then I can recreate it. But that seems pretty slow considering that my arrays can be very large.
You need to:
Loop over each inner array and count the values
Store each value and its count (if higher than current count) in a counter variable
In the end, convert the value and counts into an array
Following code shows a rough outline of the process. Remember to replace .forEach and for..in with appropriate code:
var input = [['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e']],
inputCount = {};
input.forEach(function(inner) {
var innerCount = {};
inner.forEach(function(value) {
innerCount[value] = innerCount[value] ? innerCount[value] + 1 : 1;
});
var value;
for (value in innerCount) {
inputCount[value] = inputCount[value] ? Math.max(inputCount[value], innerCount[value]) : innerCount[value];
}
});
console.log(inputCount);
// Object {a: 2, b: 3, c: 1, d: 1, e: 1}
After messing around, I found a solution but not sure if I like it enough to use. I would probably use it if I can't think of another one.
I would use underscorejs countBy to get the count of all the elements.
var array = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
var count = _.map(array, function(inner) {
return _.countBy(inner, function(element) {
return element;
});
});
var total = {};
_.each(_.uniq(_.flatten(array)), function(element) {
var max = _.max(count, function(countedElement) {
return countedElement[element];
});
total[element] = max[element];
});
console.log(total); // {a: 2, b: 3, c: 1, d: 1, e: 1}
Then I would recreate the array with that total.
Here is example of simple nested loop approach:
var input = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
var countMap = {};
// iterate outer array
for (i=0; i < input.length; i++) {
// iterate inner array
for (j=0; j < input[i].length; j++) {
// increment map counter
var value = input[i][j];
if (countMap[input[i][j]] === undefined) {
countMap[value] = 1;
} else {
countMap[value]++;
}
}
}
console.log(countMap); // output such as {'a':2, 'b':4, 'c':1, 'd':1, 'e':1}
Not the most efficient solution but it should describe you the process:
var big = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
function map(arr){
var map = {}
for (var i=arr.length-1; i>-1; i--){
if(arr[i] in map) map[arr[i]]++;
else map[arr[i]] = 1;
}
return map;
}
function reduce(matrix){
var arrMap = {};
for (var i=matrix.length-1; i>-1; i--){
var arrRes = map(matrix[i]);
for (var key in arrRes){
if( !arrMap[key] || arrMap[key] < arrRes[key])
arrMap[key] = arrRes[key];
}
}
return arrMap;
}
function calc(matrix){
var res = [],
arrMap = reduce(matrix);
for (var key in arrMap){
while(arrMap[key] > 0 ){
res.push(key);
arrMap[key]--;
}
}
return res;
}
console.log(calc(big));
// Array [ "e", "b", "b", "b", "a", "a", "d", "c" ]