2

I have made a survey in which the respondents had a multiple choice question, let's say: "What are your favorite fruits?", they can choose from a list as much as they want, but also they can introduce a custom value in case they want to add a non-listed fruit. The list have the following options: apple, pear, banana, strawberry, and "custom".

I need to make a chart with the info to count how many people chose each fruit. But I will add ALL the custom values in a value called "custom". Let's say I ended up with an array like this one:

[
  {
    "Person": "Person1",
    "Fruits": [ "apple", "banana", "peach" ]
  },
  {
    "Person": "Person2",
    "Fruits": [ "apple", "pear", "strawberry", "coconut" ]
  },
  {
    "Person": "Person3",
    "Fruits": [ "pear", "strawberry" ]
  },
  {
    "Person": "Person4",
    "Fruits": [ "strawberry", "orange" ]
  }
]

To count the already-listed fruits I started using includes(), but IE doesn't support it. So I'm using a code I've found Alternative of .includes() in Internet Explorer.

My Code:
I made a loop for each element in the array and if it includes a certain word it gets stored in its correspondent array:

//I am calling the info with AngularJS don't know if is important to know that
//Declare empty arrays for each fruit
var dataResults = $scope.items, //<---- this is the array with the info, the one I showed before..
    apple = [],
    pear = [],
    banana = [],
    strawberry = [],
    custom = [];

//function to read if an array includes a certain value
function includes(container, value) {
    var returnValue = false;
    var pos = container.indexOf(value);
    if (pos >= 0) {
        returnValue = true;
    }
    return returnValue;
}

//Loop the survey results
for(var i=0; i<dataResults.length; i++) {
    var currentItem = dataResults[i];
    //I push the name of the person if he/she chose apple
    if(includes(currentItem.Fruits, "apple")){
        apple.push(currentItem.Person);
    }
    //I push the name of the person if he/she chose pear
    if(includes(currentItem.Fruits, "pear")){
        pear.push(currentItem.Person);
    }
    //I push the name of the person if he/she chose banana
    if(includes(currentItem.Fruits, "banana")){
        banana.push(currentItem.Person);
    }
    //I push the name of the person if he/she chose strawberry
    if(includes(currentItem.Fruits, "strawberry")){
        strawberry.push(currentItem.Person);
    }
};
//now I wanna see the results in the console for each array
console.log("apple: " + apple.length);
console.log("pear: " + pear.length);
console.log("banana: " + banana.length);
console.log("strawberry: " + strawberry.length);

But now what I don't know is how many people entered a custom value. It doesn't matter what they wrote (because there can be hundreds of different values), but I need to store them all as "custom".
How can I count values that doesn't appear in the list?
Please, Help.

1

2 Answers 2

3

Looks like a good choice for a switch statement to me.

You can also remove the need to use includes().

For example:

//Loop the survey results
var currentItem, f, max;
for(var i=0; i<dataResults.length; i++) {
    currentItem = dataResults[i];
    max = currentItem.Fruits.length;
    for(f=0;f<max;f++) {
        switch(currentItem.Fruits[f]) {
            case "apple" :
                apple.push(currentItem.Person);
                break;
            case "pear" :
                pear.push(currentItem.Person);
                break;
            case "banana" :
                banana.push(currentItem.Person);
                break;
            case "strawberry" :
                strawberry.push(currentItem.Person);
                break;
            default :
                custom.push(currentItem.Person);
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

don't know why I didn't thought on using switch, it is easier and works perfectly..
1

You can check each fruit in the current item to see if it is not on the standard list. If it is not, it must be a custom fruit:

let standardList = ["apple", "pear", "banana", "strawberry"];
for(let fruit of currentItem.Fruits){
  if(!includes(standardList, fruit)){
    custom.push(currentItem.Person);
  }
}

Here is this concept applied in a working snippet:

// Object whose properties are lists, to collect people who like each fruit
var lists = {
  apple: [], pear: [], banana: [], strawberry: [], custom: []
},
// Incoming survey results
dataResults = [
  {"Person": "Person1", "Fruits": ["apple", "banana", "peach"] },
  {"Person": "Person2", "Fruits": ["apple", "pear", "strawberry", "coconut"] },
  {"Person": "Person3", "Fruits": ["pear", "strawberry"] },
  {"Person": "Person4", "Fruits": ["strawberry", "orange"] }
],
// List of standard (non-custom) fruit names
standardList = ["apple", "pear", "banana", "strawberry"];

// Loop through results
for (var i = 0; i < dataResults.length; i++) {
  const currentItem = dataResults[i];
  // Loop though the fruits in the current item
  for (let fruit of currentItem.Fruits) {
    // If fruit is on standard list, push person to a fruit-specific list
    if (standardList.indexOf(fruit) >= 0) { // Uses `indexOf` instead of `includes`
      lists[fruit].push(currentItem.Person);
    }
    // Otherwise, fruit is not on standard list, so push person to "custom" list 
    else {
      //(Assumes no more than one custom fruit per current item)
      lists["custom"].push(currentItem.Person);
    }
  }
};

// For each list in the lists object, print its name and length 
Object.keys(lists).forEach(function(name){
  console.log(`${name}: ${lists[name].length}`);
})

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.