3

first of all i am sorry if this an easy question, but iam having a difficulties to select only unique array in my program (i am just learning javasript btw). i know i can easily do this with built in function like filter or map, but i am forbidden to do that. This is what i"ve got so far :

function countUnique (numbers) { 
var sorted_numbers = numbers.sort(function(a,b){return a-b})
var result = []
for (var i = 0 ; i<numbers.length; i++){
if (numbers[i]!==numbers[i+1]){
  result.push(numbers[i])
  console.log(result)
}
}
var sum = 0
for (var j = 0; j<result.length; j++) {
sum = sum + result[j]
}
 return sum
}

console.log(countUnique([ 5, 5, 6, 6, 3, 1, 2, 7, 7])) // 6
console.log(countUnique([ 3, 6, 3, 6, 1, 1, 2, 1 ]))  // 2
console.log(countUnique([ 3, 3, 3, 3, 4, 5, 8, 10, 11 ])) // 38

Example: input: [ 5, 5, 6, 6, 3, 1, 2, 7, 7 ] proses: 3 + 1 + 2 result: 6

3
  • can you use Set operator? Commented Jul 2, 2018 at 2:42
  • well, there is no mention of Set operator, so i guess yeah Commented Jul 2, 2018 at 2:45
  • Set constructor can not filter unique values, it would just not allow to have non-unique values which is not a matter of this problem. Commented Jul 2, 2018 at 2:56

4 Answers 4

5

Use indexOf and lastIndexOf. If the result of the indexOf is equal to the result of the lastIndexOf it means that the element is unique in the array.

let arr = [ 3, 3, 3, 3, 4, 5, 8, 10, 11 ];
let sum = 0;
arr.forEach(a => {
  sum += (arr.indexOf(a) === arr.lastIndexOf(a)) ? a : 0;
});
console.log(sum);

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

1 Comment

sorry, i forget tto tell that the constraint is also indexOf
2

setup a inner loop like this

for (var i = 0 ; i<numbers.length; i++){
  for(var j = 0; j<numbers.length; j++) {
    if (numbers[i] + 1 === numbers[j]){
      result.push(numbers[i])
      console.log(result)
    }
  }
}

or use to do less loops since its sorted

  function countUnique(numbers) { 
    var sorted_numbers = numbers.sort(function(a,b){return a-b})
    var result = []
    
    /*
    for (var i = 0 ; i < numbers.length; i++){
      for(var j = 0; j < sorted_numbers.length; j++) {
        if (numbers[i] + 1 === sorted_numbers[j]){
          result.push(numbers[i]);
        }
      }
    }
    */
      
      var working = false;
      var current_count = 0;
      var counted_values = [];
       
      //create a new array for counting which numbers were used.
      for(i = 0; i < sorted_numbers.length; i++) {
        counted_values.push(0);
      }
      
      var current_value = 0;
      var put = false;
      for(var i = 0; i < sorted_numbers.length; i++) {
        current_value = sorted_numbers[i];
        put = false;
        for(var j = 0; j < sorted_numbers.length; j++) {
          if (current_value + 1 === sorted_numbers[j] && counted_values[j] == 0 && counted_values[i] == 0) {
            if(!put) {
              result.push(current_value);
              put = true; 
            }
            result.push(sorted_numbers[j]);
            counted_values[j] = 1;
            current_value = sorted_numbers[j];
          }

        }
      }

console.log(result);

    var sum = 0;
    for (var j = 0; j < result.length; j++) {
      sum = sum + result[j];
    }
    return sum;
  }

  console.log(countUnique([ 5, 5, 6, 6, 3, 1, 2, 7, 7])); // 6
  console.log(countUnique([ 3, 6, 3, 6, 1, 1, 2, 1 ]));  // 2
  console.log(countUnique([ 3, 3, 3, 3, 4, 5, 8, 10, 11 ])); // 38

5 Comments

can you elaborate more, my unserstanding of nested loop is a little bit low
the nested loop would scan from the beginning always so it won't miss a number like your loop misses since it wont be the next number it might be like 3 numbers in or more in, you have to loop it or otherwise you would need to hardcode every number in a array to check.
numbers[i]!==numbers[i+1] only checks i and i+1, but it might be i and i+5.. so you loop all the i's on the other side to check every number.
nevermind my solution is probably wrong sorry, try it out, it anyways.
I fixed it a little still don't get your numbers but thats how i understood the problem.
2

You can use objects to determine the unique number. It might be a bit complicated but it can be really useful if your arrays are lengthy.

    function countUnique(numbers){
      var counter={};
      var sum=0;
      //Record all numbers accordingly
      for(var n in numbers){
        //The current number in the array
        var num=numbers[n];
        /*
          This basically checks if the counter object contains the property
          (Which is any number in the array). If it doesn't contain it then it 
          will add it as a property with a property value of 1 
          (meaning there is currently one unique number in the array). If it does 
          contain it then it will simply add 1 to the property value indicating there is 
          more than one of the same number
        */
        (counter[num]==null)?counter[num]=1:counter[num]++;
      }
      /*
        After we are done with going through the array, we will go 
        through the object properties and only add the ones with a value of 1 
        (indicating they are unique) and add 0 if the property's value is more 
        than one
      */
      for(var c in counter){
        sum+=(counter[c]==1)?c:0;
      }
      return sum;
    }

    console.log(countUnique([ 5, 5, 6, 6, 3, 1, 2, 7, 7])); // 6
    console.log(countUnique([ 3, 6, 3, 6, 1, 1, 2, 1 ]));  // 2
    console.log(countUnique([ 3, 3, 3, 3, 4, 5, 8, 10, 11 ])); // 38

3 Comments

this looks like the best one
thank you for the insight, but i am barely touch objects :)
Oh, I apologize I forgot to take in account that you might have restrictions or that you might not understand. I have added in comments to take you through the whole process if you don't understand.
1

// Here you have the exact same arrays you used in your question
    
    const numbers1 = [ 5, 5, 6, 6, 3, 1, 2, 7, 7];  // 6
    const numbers2 = [ 3, 6, 3, 6, 1, 1, 2, 1 ];  // 2
    const numbers3 = [ 3, 3, 3, 3, 4, 5, 8, 10, 11 ]; // 38

// Here we have a function that finds non-repeating numbers
// We don't only remove duplicates if a number appears more than once, we don't include it at all

    function notRepeatedNum(arr) {
     let result = [];
     let ctr = 0; 
      for (let x = 0; x < arr.length; x++) {
       ctr = 0;
      for (let y = 0; y < arr.length; y++) {
      if (arr[x] === arr[y]) {   // If we have a match increment the counter by 1
        ctr+= 1;
        }
       }

 // If the counter is >= 2 then the number is repeating, otherwise push it to the array

    if (ctr < 2) {
      result.push(arr[x]);
      }
    }
    return result;
    }

// Here we use the function to find those non-repeating and store it in a variable 
    
    const nonReapiting1 = notRepeatedNum(numbers1);
    const nonReapiting2 = notRepeatedNum(numbers2);
    const nonReapiting3 = notRepeatedNum(numbers3);
    
// Here we are summing the non-repeating numbers into a single value
    
    function sumIt(numbers) {
      let sum = 0;
      for (let b = 0; b < numbers.length; b++) {
        sum += numbers[b];
      }
      return sum;
    }

// And finally we log it to the console :)

console.log(sumIt(nonReapiting1));  // 6
console.log(sumIt(nonReapiting2));  // 2
console.log(sumIt(nonReapiting3));  // 38

Note: This could have been done a lot faster, cleaner, and in a much more efficient way, with array helpers, but I'm pretty sure this is what you asked for. No Babel/ ES6, not even objects ware used :)

Run the code snippet and see if this workes for you

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.