Removing empty strings from array - javascript

I understand there are other pages on this but I am trying to get my own working and I do not know why it is not working. I am new to node.js.
for (var index in output)
{
if (opt.options.showEmpty != true)
{
var check = arrayIsEmpty(output[index]);
if ( check == true )
{
continue;
}
else
{
var array = removingEmptyString(output[index]);
console.log(index + "\t" + array);
//console.log(index+ "\t" + output[index]);
}
}
}
function removingEmptyString(array)
{
var newArray;
for( var i = 0; i < array.length; i++)
{
if(array[i] != "" || array[i] != null)
{
newArray[i] = array[i];
}
}
return newArray;
}
My result is tree,,, that i was previously getting before the code i wrote. now i get an error of
newArray[i] = array[i];
^
TypeError: Cannot set property '0' of undefined
at removingEmptyString (librarySeeker.js:130:18)
at result (librarySeeker.js:76:19)
at /async/lib/async.js:226:13
at async/lib/async.js:113:25
at async/lib/async.js:24:16
at async/lib/async.js:223:17
at /async/lib/async.js:510:34
at IncomingMessage.<anonymous> (pull.js:295:10)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:910:16

You could just use the .filter method in Array's prototype.
var pirate = ['a','1','',0];
function arr (value) {
return value.filter(function (item) {
return item !== '';
});
}
arr(pirate);
// <- ['a','1',0]
As an alternative, you might want to consider naming the callback to .filter
var pirate = ['a','1','',0];
function worthy (value) {
return value !== '';
}
pirate.filter(worthy);
// <- ['a','1',0]

In the spirit of learning, here is a working version of your solution:
function removingEmptyString(array) {
'use strict';
var newArray = []; // don't forget to initialize it
for( var i = 0, len = array.length; i < len; i += 1) {
if(typeof array[i] === 'string' && array[i].length > 0) {
// add the string to the end of the new array
newArray.push(array[i]);
}
}
return newArray;
}

The error is saying that newArray has not been initialised, so it cannot assign the 0 property to an undefined object.
You can improve your function to make it work:
function removingEmptyString(array){
var newArray = [];
for( var i = 0; i < array.length; i++){
// empty string and null are falsy values by default is js
if(array[i])
{
// use this if you want to keep "undefined" values in the newArray in place
// of the null ones in the original array
newArray[i] = array[i];
// otherwise just push the values in the new array
// newArray.push(array[i]);
}
}
return newArray;
}

Related

How do I build an object counting occurrences in an Array in JavaScript?

I want to count how often a number in an Array occurs. For example, in Python I can use Collections.Counter to create a dictionary of how frequently an item occurs in a list.
This is as far as I've gotten in JavaScript:
var array = [1,4,4,5,5,7];
var obj = {};
for (var i=0; i < array.length; i++) {
/* obj[array[i]] = +=1 */ <= pseudo code
}
How can I create this frequency counter object?
Close but you can't increment undefined so you need to set initial value if it doesn't exist
var array = [1,4,4,5,5,7];
var obj = {};
for (var i=0; i < array.length; i++) {
obj[array[i]] = (obj[array[i]] || 0) +1 ;
}
You were almost there. See below code:
var array = [1,4,4,5,5,7];
var obj = {};
for (var i=0; i < array.length; i++) {
obj[array[i]] = (obj[array[i]] || 0 ) +1;
}
console.log(obj);
Create an object and check if that specific key exist.If exist then increase it's value by 1
var array = [1, 4, 4, 5, 5, 7];
var obj = {};
for (var i = 0; i < array.length; i++) {
if (obj.hasOwnProperty(array[i])) {
obj[array[i]] += 1;
} else {
obj[array[i]] = 1;
}
}
console.log(obj)
You can use the ? : ternary operator to set initial value as 1 and then increment it on subsequent matches.
var array = [1,4,4,5,5,7];
var obj = {};
for (var i=0; i < array.length; i++) {
obj[array[i]] = obj[array[i]]?obj[array[i]]+1:1;
}
console.log(obj);
If the array is always going to be same, and you are going to check frequency of multiple items in the same array without it it being modified, #JohanP's answer is good.
But if you are only going to check frequency of only one item, or the array can change, creating the object is nothing but extra overhead.
In that case, you can do something like this:
const getItemFrequency = function(array, item) {
return array.filter(i => i === item).length;
}
var array = [1,4,4,5,5,7];
console.log(getItemFrequency(array, 4));
Concise logic written as proper function:
function countArrayItemFrequecy(array) {
const length = array.length;
const map = {};
for ( let i = 0; i < length; i++ ) {
let currentItem = array[i];
if (typeof map[currentItem] !== 'undefined' ) {
map[currentItem]++
} else {
map[currentItem] = 1
}
}
return map;
}
You need to make sure to assign default value to your frequency object for the first occurrence of the item. As a shortcut you can use ternary operator
var array = [1,4,4,5,5,7];
var obj = {};
for (var i=0; i < array.length; i++) {
obj[array[i]] = obj[array[i]] ? obj[array[i]]++ : 1;
}
which is the same as:
var array = [1,4,4,5,5,7];
var obj = {};
for (var i=0; i < array.length; i++) {
if (obj[array[i]]) {
obj[array[i]]++;
} else {
obj[array[i]] = 1;
}
}
You can use Object.assign: below clones map and then increments/adds the counter. These are pure (no side effects/param reassignment), single-purpose functions.
addToMap does the same thing as { ...map, map[e]: [e]: (map[e] || 0) + 1 }, but that requires babel.
const addToMap = (map, e) => Object.assign({}, map, { [e]: (map[e] || 0) + 1 });
const buildMap = a => a.reduce(addToMap, {});
Using Array.reduce:
arr.reduce(function (acc, item) {
acc[item] = (acc[item] || 0) + 1;
return acc;
}, {});
Example:
var arr = [1,1,2,4,1,4];
var counts = arr.reduce(function (acc, item) {
acc[item] = (acc[item] || 0) + 1;
return acc;
}, {});
console.log(counts);

Javascript - Permutations remove the duplicates elements

that is found here in stack but i want somes changes.
function perms(data) {
if (!(data instanceof Array)) {
throw new TypeError("input data must be an Array");
}
data = data.slice(); // make a copy
var permutations = [],
stack = [];
function doPerm() {
if (data.length == 0) {
permutations.push(stack.slice());
}
for (var i = 0; i < data.length; i++) {
var x = data.splice(i,1);
stack.push(x);
doPerm();
stack.pop();
data.splice(i, 0, x);
}
}
doPerm();
return permutations;
}
var input = "552".split('');
var result = perms(input);
for (var i = 0; i < result.length; i++) {
result[i] = result[i].join('-');
}
The result of that is :
5-5-2
5-2-5
5-5-2
5-2-5
2-5-5
2-5-5
but , are 3 elements duplicates the result must be :
5-5-2
5-2-5
2-5-5
how can i fix that issue .
Basically, you have one issue,
var x = data.splice(i, 1)[0];
// ^^^ is missing
because you get an array with splicing. The result is a deep nested array with
data.splice(i, 0, x);
This inserts the array later on position i.
For preventing duplicates, you need a check, if the actual value is already inserted in the result set with
permutations.some(function (a) {
return a.every(function (b, j) {
return stack[j] === b;
});
}) || permutations.push(stack.slice());
which test the arrays and if no match, the push is performed.
function perms(data) {
if (!(data instanceof Array)) {
throw new TypeError("input data must be an Array");
}
data = data.slice(); // make a copy
var permutations = [],
stack = [],
hash = Object.create(null);
function doPerm() {
if (data.length == 0) {
permutations.some(function (a) {
return a.every(function (b, j) {
return stack[j] === b;
});
}) || permutations.push(stack.slice());
return;
}
for (var i = 0; i < data.length; i++) {
var x = data.splice(i, 1)[0];
stack.push(x);
doPerm();
stack.pop();
data.splice(i, 0, x);
}
}
doPerm();
return permutations;
}
var input = "552".split('');
var result = perms(input);
for (var i = 0; i < result.length; i++) {
result[i] = result[i].join('-');
}
console.log(result);
Check if array array is present within resulting array before calling .push() using Array.prototype.some(), Array.prototype.join()
function p(a, b, res) {
var b = b || [],
res = res || [],
len = a.length;
if (!len) {
// check if `res` contains `b.join("")`
if (!res.length
|| !res.some(function(n) {
return n.join("") === b.join("")
}))
res.push(b)
} else {
for (var i = 0
; i < len; p(a.slice(0, i).concat(a.slice(i + 1, len))
, b.concat(a[i]), res)
, i++);
}
return res
}
var result = p("552".split(""));
result = result.map(function(res) {
return res.join("-")
});
console.log(result);

javascript array - increment value at given key

I have a dynamic array and I am trying to increment the value by 1 if the key exists in the array. According to my debug it is incrementing the key and and creating a second key/value pair.
A snippet of my code:
for (var i = 0; i < choices.length; i++) {
console.log(choices[i]);
if (choices[i].YearTermId == 1) {
if (!lookup(firstChoice, choices[i].FirstChoiceOptionId)) {
firstChoice.push({
key: choices[i].FirstChoiceOptionId,
value: 1
});
} else {
firstChoice[choices[i].FirstChoiceOptionId] = firstChoice[choices[i].FirstChoiceOptionId] + 1;
}
more if/else..
function lookup( arr, name ) {
for(var i = 0, len = arr.length; i < len; i++) {
if( arr[ i ].key === name )
return true;
}
return false;
}
You're using an array where you should be using an object. If you use an object, your code can be rewritten as:
var firstChoice = {};
for (var i = 0; i < choices.length; i++) {
var firstChoiceOptionId = choices[i].FirstChoiceOptionId;
if (choices[i].YearTermId == 1) {
firstChoice[firstChoiceOptionId] = firstChoice[firstChoiceOptionId]
? firstChoice[firstChoiceOptionId] + 1
: 1;
/* ... */
}
}
If you need the data as an array afterwards, just map it:
var firstChoiceArray = Object.keys(firstChoice).map(function(key) {
return {
key: key,
value: firstChoice[key]
};
});
Conversely, if you have an input array and want to convert it to an object for manipulation, reduce it:
var firstChoice = firstChoiceArray.reduce(function(result, current) {
result[current.key] = current.value;
return result;
}, {});
I think you should increment value key, like:
firstChoice[choices[i].FirstChoiceOptionId].value ++;
And I would like to rewrite this code to:
var firstChoice = {};
for (var i = 0; i < choices.length; i++) {
if (choices[i].YearTermId == 1) {
if (!firstChoice[choices[i].FirstChoiceOptionId]) {
firstChoice[choices[i].FirstChoiceOptionId] = 0;
}
firstChoice[choices[i].FirstChoiceOptionId]++;
}
}
console.log(firstChoice);
Try with Array.map:
Example:
var a = [{key:"ab","value":1},{key:"cd","value":1},{key:"ef","value":1}];
a.map(function(item){if(item.key == this){item.value++}}, "cd");
So, a[1] will have value 2 after that.

Javascript for looping over array argument

I am trying to loop over an array argument and return the first n elements of the passed array without using standard javascript functions such as slice, concat, push, pop etc...
var n = 0;
var anyArray = Array;
var SR = {};
SR.first = function(anyArray,n){
var isArray = (Object.prototype.toString.apply(anyArray) === '[object Array]');
var specification = (typeof n === "number");
if(isArray && specification){
for(i = 0; i < n; i++){
return Array(anyArray[i]);
}
}
else if (isArray || !specification){
return anyArray[0];
}
}
I do not want to build the return array "anyArray" by using +=. So, how would I proceed to have it return some thing like this [1,2,3,4] when "SR.first([1,2,3,4,5,6,7], 4);" is called?
var newArr = Array.apply(null, anyArray); // new Array using original content
newArr.length = n; // truncate the length of the new Array
return newArr; // return it
One small edge case will be when anyArray has only one member, which is a number. You'll need to guard against that scenario.
I don't understand why you would not want to use Array operations like push and slice, but this would work:
if ( isArray && specification ) {
var result = [];
for ( var i = 0; i < n; i++ ) {
result[i] = anyArray[i];
}
return result;
}
else ...
If for some reason you really don't want to use native javascript functions, you can assign each element to your return array one by one.
var returnArray = [];
if(isArray && specification) {
for(i = 0; i < n; i++) {
returnArray[i] = anyArray[i];
}
}
return returnArray;
SR.first = function(anyArray,n){
var newArray = [];
for(i = 0; i < n; i++){
newArray[newArray.length] = anyArray[i];
}
return newArray;
}
First of all - global variable it's really bad practice! You don't need declare anyArray and n, becouse its a function arguments, and its declared on function call.
Second problem - that you can put number of elements bigger than array length - you must check this situation.
var SR = {};
SR.first = function(anyArray,n){
var isArray = (anyArray instanceof Array),
specification = (typeof n === 'number'),
tmp = new Array;
console.log(isArray, specification);
if(isArray && specification){
for(i = 0, l = anyArray.length; i < n && i < l; i++){
tmp[i] = anyArray[i];
}
return tmp;
} else if (isArray || !specification){
return anyArray[0];
}
}

Knowing position of a value under twodimensional Array

I have a SummaryData array as shown
var summaryData = [[0,100.34],[1,102.31],[2,131.08],[3,147.94],[4,172.55],[5,181.05],[6,180.08]];
My question is:
Is it possible to find out what the position of a value is?
(For example, how can I know where 147.94 is?) (I am expecting "3")
Update:
A more prototype-y way:
var result = summaryData.detect(function(item) { return item[1] === 147.94; });
alert(result[0]);
Or:
function getKey(arr, value) {
var key = null,
item;
for (var i = 0; i < arr.length && !key; i++) {
item = arr[i];
if (item[1] === value) {
key = i;
}
}
return key;
}
Usage:
var n = getKey(summaryData, 147.94); // returns 3.
At the risk of doing your homework for you...
var summaryData = [[0,100.34],[1,102.31],[2,131.08],[3,147.94],[4,172.55],[5,181.05],[6,180.08]];
function findPosition(value, dataArray) {
var a;
for (var i=0, iLen=dataArray.length; i<iLen; i++) {
a = dataArray[i];
for (var j=0, jLen=a.length; j<jLen; j++){
if (value == a[j]) {
return i + ',' + j;
}
}
}
}
alert(findPosition(131.08, summaryData)); // 2,1
The above returns the position of the first match.
Edit
I see now that you don't need to iterate over the second array, just look at the second value, so:
function findPosition(value, dataArray) {
var a;
for (var i=0, iLen=dataArray.length; i<iLen; i++) {
a = dataArray[i];
if (value == a[1]) {
return a[0];
}
}
}
alert(findPosition(131.08, summaryData)); //2
Or if the data format is always as specified and there may be thousands of values, then it may be much faster to do:
function findPosition(value, dataArray) {
var re = new RegExp('[^,],' + value);
var m = dataArray.join().match(re);
return m && m[0].replace(/,.*/,'');
// Or
// return m && m[0].split(',')[0];
}
function getPosition(candidate) {
var i = summaryData.length;
while (i) {
i -= 1;
if (summaryData[i][1] === candidate) {
return summaryData[i][0];
}
}
}

Categories

Resources