Использование позиции индекса для фильтрации массива по значениям в другом массиве - javascript

Я работаю с чрезвычайно большим кубом данных, которым мне нужно манипулировать для целей визуализации данных. У меня есть многомерный массив, содержащий массивы всех возможных комбинаций объектов, причем конечный объект каждого массива является ассоциированным значением.

Я использую несколько входов (каждый с перечисленным идентификатором на основе индекса значения в данных), чтобы пользователи могли фильтровать результаты по каждому объекту в массиве, за исключением последнего объекта, который отображается как "всего доступного". Исходя из этих входных данных, я собираю выборки в переменную так, чтобы индекс выборок соответствовал позиции индекса соответствующего значения в данных.

var selections = [];
var data = [[val0, val1, val2, 5121231], [val0, val1, val2, 2242], [val0, val1, val2, 72356], [val0, val1, val2, 24122], [val0, val1, val2, 75632]];

$('#fields').change(function(){
    for (var i = 0; i < data[0].length; i ++){
        selections[i] = $('select#field' + i).val();
    }
});

Это создаст многомерный массив, который выглядит следующим образом:

selections = [[data[0][0], data[1][0], data[2][0], data[3][0], data[4][0]], [data[0][1], data[1][1], data[2][1], data[3][1], data[4][1]], [data[0][2], data[1][2], data[2][2], data[3][2], data[4][2]], [data[0][3], data[1][3], data[2][3], data[3][3], data[4][3]]]

То, что я пытаюсь сделать, это отфильтровать данные так, чтобы для ВСЕХ выбранных выборок, если data[x][i] === какое-либо значение в выборках [i], data[x] заполняется в новый массив.

Какие-нибудь мысли?

*****ОБНОВИТЬ*****

Огромное спасибо Дэйву за помощь! Мы смогли установить зависимые выпадающие фильтры, которые манипулируют многомерным массивом без ключей (куб данных). Если вы работаете с большими наборами данных в браузере, взгляните на решение. Вот что он / мы придумали:

https://jsfiddle.net/JSnoobDC16/yteu6cbb/28/

1 ответ

Решение

Поскольку вы используете jQuery, это легко можно решить с помощью $.grep() в сочетании с Array.some(),

var newArray = $.grep(data, function(item) {
  return selections.some(function(selectedValue, i) {
    return selectedValue.indexOf(item[i]) >= 0;
  });
});

Ниже приведен полный фрагмент и обновленная скрипка: https://jsfiddle.net/gh8fzxLh/

//function to initialize the materialize dropdowns
function pageReady() {
  $(document).ready(function() {
    $('select').material_select();
  });
}

//function to get the sum of object elements
function sum( obj ) {
  var sums = 0;
  for( var el in obj ) { 
    if( obj.hasOwnProperty( el ) ) {
      sums += parseFloat( obj[el] );
    }
  }
  return sums;
}

//function to return array of all values at a certain index positon
function getFields(matrix, index){
  var fields = [];
  for (var i = 1; i<matrix.length; i++ ){
    fields.push(matrix[i][index]);
  }
  return fields;
}

//function to return only unique values from array
function unique(arr) {
  var hash = {}, uniqueArr = [];
  for ( var i = 0, l = arr.length; i < l; ++i ) {
    if ( !hash.hasOwnProperty(arr[i]) ) { 
      hash[ arr[i] ] = true;
      uniqueArr.push(arr[i]);
    }
  }
  return uniqueArr;
}

//importing data set
var data = [
  ["state", "gender", "martial staus", "ethnicity"],
  ["GA", "null", "null", "Caucasian", 5086317],
  ["FL", "", "null", "null", 4338099],
  ["IN", "M", "null", "African-American", 72238],
  ["GA", "", "married", "Caucasian", 390578],
  ["MO", "null", "null", "Caucasian", 4165871],
  ["MO", "", "married", "Caucasian", 344501],
  ["NY", "null", "null", "African-American", 1204504],     ["AR", "M", "single", "Caucasian", 164311],
  ["CO", "null", "married", "null", 551192],
  ["OH", "null", "married", "Caucasian", 1017924],
  ["LA", "M", "null", "East Asian", 3229],
  ["AZ", "F", "single", "Uncoded", 21302],
  ["AR", "", "married", "Middle Eastern", 187]
];

var selections = []; //variable to hold all selected values
var valCombos = data[0].length; //establishing number of dropdown selection objects

/* Adding multiselection dropboxes (and soon to be other data inputs)
for each field. */
for (var i = 0; i < valCombos; i ++){
  var options = unique(getFields(data, i)).sort();
  $('#selectBar').append('<div class="row section params" id="fieldRow' + i + '"><div class="col s12 input-field" id="fieldparams"><select class="fields" id="field' + i + '" multiple><option value="" disabled selected>Select Values</option></select><label>' + data[0][i] + '</label></div></div>');
  $.each(options, function (index, value) {
    $('#field' + i).append('<option value="' + value + '">' + value + '</option>');
  });
}

pageReady();

/*Updating "selections" array as user makes selections. 
"Selections" will be used to filter the cube for visualizations. */
$('.fields').change(function(){
  for (var i = 0; i < valCombos; i ++) {
    selections[i] = $('select#field' + i).val();
  }
  console.log(selections);

  var selectedData = getSelectedData(data, selections);
  
  console.log(selectedData);
  $("#count").text(sumData(selectedData));

});

function getSelectedData(data, selections) {
  return $.grep(data, function(item) {
    return selections.some(function(value, i) {
      return value.indexOf(item[i]) >= 0;
    });
  });
}

function sumData(selectedData) {
  return selectedData.reduce(function(prev, current) {
    return prev + current[current.length - 1];  
  }, 0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/css/materialize.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/js/materialize.min.js"></script>
<div id="count">
  Sum of lastIndexOf values displays here
</div>
<div id="selectBar">
</div>

Другие вопросы по тегам