1

this is the problem description: Given an array of integers, calculate the fractions of its elements that are positive, negative, and are zeros. Print the decimal value of each fraction on a new line. for example given the array arr=[1,1,0,-1,-1] output should be:

0.400000
0.400000
0.200000

I know there is more more simple solution for it ,and i am sorry for my silly simple question but i wanna make my code work, my code sorts the output based on the key and removes duplicates. for this arr, my code output is:

0.200000
0.400000

thank you so much in advance for any help.

function plusMinus(arr) {
    var freq = {};
    for (var i = 0; i < arr.length; i++){
        if (freq[arr[i]]) {
            freq[arr[i]]++;
        } else {
            freq[arr[i]] = 1;
        }
    } for(var key in freq){

        console.log((freq[key]/arr.length).toFixed(6));
    }
    }
0

7 Answers 7

2

You could take an object with predifined properties, this prevents each loop for checking the existence and take an array of keys for getting the result in a wanted order.

function plusMinus(arr) {
    var freq = { 1: 0, '-1': 0, 0: 0 },
        i, key;

    for (i = 0; i < arr.length; i++) {
        freq[arr[i]]++;
    }

    for (key of [1, -1, 0]) {
        console.log((freq[key] / arr.length).toFixed(6));
    }
}

plusMinus([1, 1, 0, -1, -1]);

Sign up to request clarification or add additional context in comments.

4 Comments

The number can be any integer according the question. You might have to do: freq[Math.sign(arr[i])]++
@adiga, right, for any integer, the sign sould be sufficient.
@NinaScholz the order is right now but still deletes duplicates, the output should be 0.4,0.4,0.2 but its giving 0.4,0.2 , why is that?
i don't understand the last output. what do you get?
0

Let's make sure the order of key in the map by defining it first.

function plusMinus(arr) {
  var freq = {
    posetive: 0,
    negative: 0,
    zero: 0
  };
  for (var i = 0; i < arr.length; i++){
    if( arr[i] < 0) {
      freq.negative++;
    } else if(arr[i] > 0) {
      freq.posetive++;
    } else {
      freq.zero++;
    }
  } 
  for(var key in freq){
    console.log((freq[key]/arr.length).toFixed(6));
  }
}
plusMinus([1,1,0,-1,-1]);

Comments

0

You can use reduce.

Here idea is

  • First loop through original array and check for the value.
  • If value is zero we increment count of zero key.
  • If value is positive we increment count of pos key.
  • If value is negative we increment count of neg key.
  • Finally we divide each count by length of array.

let arr = [1,1,0,-1,-1]

let op = arr.reduce((op,inp)=>{
  if(inp === 0){
    op.zero.count++
  } else if (inp > 0){
    op.pos.count++;
  } else {
    op.neg.count++;
  }
  return op
},{zero:{count:0},pos:{count:0},neg:{count:0}})


let final = Object.entries(op).map(([key,value])=>({
  [key] : value.count / arr.length
}))

console.log(final)

Comments

0

Use reduce, map and filter:

const arr = [1, 1, 0, -1, -1];

const counts = arr.reduce((acc, curr) => {
  if (!curr) acc[0]++;
  else if (curr > 0) acc[1]++;
  else acc[2]++;
  return acc
}, [0, 0, 0]);

const result = counts.map(e => e / arr.length).filter((e, i, a) => a.indexOf(e) == i);

console.log(result);

Comments

0

You can try using Array.reduce and the resulting array will have the fraction of positive number at the '0'th index, negative at '1'st and zero at the '2'nd index.

Now if you want to control the count of the number of elements after decimal point, use Array.map at the end to transform it.

const array = [1,1,0,-1,-1];
function plusMinus(arr){
  const output = arr.reduce((acc, ele) => {
  if(ele > 0){
    acc[0] = ((acc[0] || 0 ) + 1 / arr.length);
  }
  if(ele < 0){
    acc[1] = ((acc[1] || 0 ) + 1 / arr.length);
  }
  if(ele === 0) {
    acc[2] = ((acc[2] || 0 ) + 1 / arr.length);
  }
  return acc;
  }, []).map(ele => ele.toFixed(6));
 console.log(...output);
}
plusMinus(array);

Comments

0

Math.sign is your friend here. Math.sign

Also lodash would really help this snippet to be cleaner, I highly recommend _.countBy. Lodash .countBy

Here's the code.

const plusMinus = (numbers) => {
  // Count by Sign (-1, 0 1)
  const countSign = _.countBy(numbers, Math.sign);
  // _.countBy return object, of counted { '1': 2, '0': 1, '-1': 2 } 
  
  // Print them in orders
  const printOrder = [1, -1, 0];
  printOrder.forEach(sign => {
    console.log((countSign[sign] / numbers.length).toFixed(6));
  });
}

const testArr = [1,1,0,-1,-1];
plusMinus(testArr);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

Comments

0

Here is another one-line solution using Array.reduce() and Array.forEach() functions:

const plusMinus = arr => arr
  .reduce((res, curr) => ++res[!curr ? 2 : curr < 0 ? 1 : 0] && res, [0, 0, 0])
  .forEach(i => console.log((i / arr.length).toFixed(6)));

plusMinus([1, 1, 0, -1, -1]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.