12

I have a JavaScript array:

var j_array = new Array();
j_arry=["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"];

I need to find how many times the class is coming and its array key, so I use:

found = $.inArray('class', j_array); ` But it returns `-1`;

Then I use:

var search = 'class';
$.each([j_array], function(index, value){
    $.each(value, function(key, cell){
        if (search.indexOf(cell) !== -1)
            console.log('found in array '+index, cell);
    });
});

But that is also wrong. How do I solve this?

From this array I want to get the following:

  1. Class coming 4 times, at key 0, 2, 3, and 7

  2. I want to make a separate array of class only, that is,

    new_array = ["class:1", "class:2", "class:3", "class:10"];
    
  3. Currently there are four classes in j_array. How can I get the Nth class value

That is, 1st class value ="class:1", 2nd class value="class:5", etc.

kukkuz
  • 41,512
  • 6
  • 59
  • 95
Kamal
  • 163
  • 5

7 Answers7

13

You could filter elements which match in a new array and just return the length of this new array

var j_arry = ["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"];
var res = j_arry.filter(x => x.includes("class"));
var key = res.map(x => x.split(":")[1]);
console.log("Class coming " + res.length + " , at key " + key.join(","));
console.log("new array = ", res);
kevin ternet
  • 4,514
  • 2
  • 19
  • 27
8

Use Array.prototype.filter to filter out the elements of the array that contains the string class - see demo below:

var j_array =["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"];

var result = j_array.filter(function(e){
  return e.indexOf('class')!==-1;
});

console.log(result);

EDIT:

To get the list of indexes too, you can try this:

var j_array =["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"];

var filteredIndices = []

var filtered = j_array.filter(function(e,i){
  if(e.indexOf('class')!==-1) {
    filteredIndices.push(i);
    return true;
  } else {
    return false;
  }
});

console.log(filtered);
console.log(filteredIndices);

// Nth class value
console.log(filtered[2]); // this prints the 3rd one
.as-console-wrapper{top:0;max-height:100%!important;}
kukkuz
  • 41,512
  • 6
  • 59
  • 95
3

Here is the answer to your questions 1 + 2. It is also 'n' proof so answers your part 3 also. This works by old-fashioned hard graft rather than funky functions. The original array entries are split and filtered then if qualifying we store in an associative array (results) using a pointer array (list) to make it easier to give a sorted result and pull the values from the associative array. The max variable is probably not necessary but included for clarity - could have used list.length instead. Note that the list[] array will be sparse (missing steps) so we test each entry before use in the output steps.

  var j_array = new Array();
  j_arry=["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10","class:1"];

  var a, result = [], list=[], max = -1    
  for (var i =0; i < j_arry.length; i = i + 1) {

   var a = j_arry[i].split(":")
    if ( a[0] === "class") {
    
    var key = "c" + a[1]
     if ( !result[key] ) { result[key] = {pos:[]}}
    result[key].cnt = result[key].cnt ? result[key].cnt + 1 : 1; 
     result[key].pos.push(i)
     list[parseInt(a[1])] = "c" + a[1]  
     
     max = parseInt(a[1]) > max ? a[1] : max;
    }
  }

  // say locations
  for (var i = 0; i < max; i = i + 1) {
   if (list[i]) {
   key = "c" + i 
    console.log("Class " + i + " occurs  at " + result[key].pos.toString()  )
    }
  }

  // make new array
  var newArray=[]
  for (var i = 0; i < max; i = i + 1) {
   if (list[i]) {
    newArray.push("Class:" + i)
    }
  }
  console.log("New array=" + newArray.toString()  )

Results are:

Class 1 occurs at 0,8 Class 3 occurs at 3 Class 5 occurs at 2 New array=Class:1,Class:3,Class:5

Vanquished Wombat
  • 9,075
  • 5
  • 28
  • 67
3

Single reduce is sufficient here.

var arr = ["class:1","division:a","class:5","class:3","division:b","division:c","division:d","class:10"],
    res = arr.reduce((p,c) => c.includes("class") ? (p.count++, p.keys.push(c.split(":")[1]), p)
                                                  : p ,{count:0, keys:[]});
console.log(res);
Redu
  • 25,060
  • 6
  • 56
  • 76
3

You can use the filter and map functions to filter your array to have only elements that match the text 'class', and use array index notation to access the nth element in the array. Check the below code snippet I hope it will be of help to you.

The below code snippet uses ES6 arrow syntax.

var arr = ["class:1", "division:a", "class:5", "class:3", "division:b", "division:c", "division:d", "class:10"];
var result = arr.filter(x => x.indexOf('class') !== -1);
var indices = result.map(x => arr.indexOf(x));
console.log(indices);
console.log(result);

var nValue = window.prompt('Enter n value');
console.log(result[nValue]);
Abdul Mateen Mohammed
  • 1,864
  • 1
  • 12
  • 21
3

If you're using jQuery to support some really old browser that still don't implement the new Array functions, and you don't want to polyfill those because you're already using jQuery, then you can use the jQuery equivalents:

var arr = ["class:1", "division:a", "class:5", "class:3", "division:b", "division:c", "division:d", "class:10"]
var result = $.grep(arr, function (x) { return x.indexOf('class') !== -1 })
var indices = $.map(result, function (x) { return arr.indexOf(x) })

This is the same code as this answer, but using jQuery.

Community
  • 1
  • 1
Gustavo Rodrigues
  • 3,517
  • 1
  • 25
  • 21
1

You have to do map first then filter.

var j_array = ["class:1", "division:a", "class:5", "class:3", "division:b", "division:c", "division:d", "class:10"];

var result = j_array.map(function(e, i) {
  return e.indexOf('class') > -1 ? '' + i : false;
}).filter(function(e) {
  return !!e;
});
console.log(result);
kukkuz
  • 41,512
  • 6
  • 59
  • 95
Anil Talla
  • 709
  • 5
  • 19