0

I have a list of items in an array and i want to create a new array that is an array of objects with the key being the value from the existing array and the value being the number of times that item was in the existing array. Hope that makes since, if not hopefully this example will help. No third party libraries like lodash or underscore please.

Any help would be greatly appreciated, thank you.

var arr = [a,a,a,b,c,c,d,e,f,f,f,f];
new array =[{a:3},{b:1},{c:2},{d:1},{e:1},{f:4}];

My attempt so far:

            countryCodes.sort();
            var result = count(countryCodes);
            console.log(result[0]+": "+result[1]);
            function count(arr) {
                var a = [], b = [], prev;
                arr.sort();
                for ( var i = 0; i < arr.length; i++ ) {
                    if ( arr[i] !== prev ) {
                        a.push(arr[i]);
                        b.push(1);
                    } else {
                        b[b.length-1]++;
                    }
                    prev = arr[i];
                }
                return [a, b];
            }
3

4 Answers 4

2

You're close.

var a = "aa",
    b = "bb",
    c = "cc",
    d = "dd",
    e = "ee",
    f = "ff";

var arr = [a,a,a,b,c,c,d,e,f,f,f,f];

function getCount(arr) {
  var result = {};
  
  for (var val of arr) result[val] = result[val] + 1 || 1;
  
  return result;
}

var totals = getCount(arr);
document.write(JSON.stringify(totals));

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

2 Comments

it's almost like magic on how you come up with some of these answers.They make complete sense when i read them but coming up with on my own is going to take a lot more practice. Your answer was actually exactly what i was looking for even though i did not ask for it in the correct wording.Thank you.
Neat..! I liked the shortcut.
1

Open console when press run button.

var arr = ['a', 'a', 'a', 'b', 'c', 'c', 'd', 'e', 'f', 'f', 'f', 'f'];

function getObjectFromArray(a) {
  var result = [],
      alreadyAdded = [];
  a.forEach(function(item) {
    var key = item,
      obj = {};
    if (alreadyAdded.indexOf(item) != -1) return;
    alreadyAdded.push(item)
    obj[key] = getCount(a, item)
    result.push(obj)
  })

  return result;
}

function getCount(a, el) {
  var count = 0;
  a.forEach(function(element) {
    if (element == el) count++
  })

  return count;
}

console.log(getObjectFromArray(arr))

1 Comment

Thank you @t1m0n. I definitely need to practice my arrays and objects, as i get a little lost when trying to figure out these kind of situations. Again, thank you.
1

Here is another working way.

   function count(arr) {
    var prev = arr[0];
    var current;
    var newArr = [];
    var count = 0;
    var obj = {};
    for (var i = 0; i < arr.length; i++) {
        current = arr[i];
        if (i == arr.length - 1) {
            if (prev == current) { 
                count++;
                obj = {};
                obj[prev] = count;
                newArr.push(obj);
            }
            else {
                obj = {};
                obj[prev] = count;
                newArr.push(obj);
                count = 1;
                obj = {};
                obj[current] = count;
                newArr.push(obj);
            }
        }
        else if (prev == current) {
            count++;
        }
        else {
            obj = {};
            obj[prev] = count;
            newArr.push(obj);
            count = 1;
            prev = current;
        }
    }
    return newArr;
}
        console.log(count(['a', 'a', 'a', 'b', 'c', 'c', 'd', 'e', 'f', 'f', 'f', 'f']));

Comments

1

This can be a very simple task with Array.prototype.reduce()

var arr = ["a","a","a","b","c","c","d","e","f","f","f","f"],
    res = arr.reduce((p,c) => { var i = p.findIndex(e => !!e[c]);
                                !!~i ? p[i][c]++ : p.push({[c]:1});
                                return p},[]);

document.write("<pre>" + JSON.stringify(res) + "</pre>");

OK the below one should be faster like o(2n) and it's nothing more longer than two lines of object assignments.

var arr = ["a","a","a","b","c","c","d","e","f","f","f","f"],
    mid = arr.reduce((p,c) => {!!p[c] ? p[c]++ : p[c]=1; return p},{}),
    res = Object.keys(mid).map(e => ({[e]:mid[e]}));

document.write("<pre>" + JSON.stringify(res) + "</pre>");

3 Comments

This has runtime in O(n^2), which might matter if you are trying to process a large list.
This is using ecma6 and i am unable to use babel as a third party library. But good to know and well written, thanks!
@Travis Michael Heller thank you... the second snipped should be ok with ES5 though...

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.