Подтвердить что ты не робот

Получить ключи объектов для отфильтрованных значений

Случай прост - у меня есть следующий объект:

Object {1: false, 2: true, 3: false, 4: false, 5: false, 6: false, 7: false, 8: true, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false} 

и мне нужно получить массив идентификаторов, которые имеют истинное значение, используя знак подчеркивания. В приведенном выше случае это будет:

[2, 8]

Я пробовал несколько вещей, но я немного застрял. Кто-нибудь знает?

4b9b3361

Ответ 1

var keys = [];
_.each( obj, function( val, key ) {
  if ( val ) {
    keys.push(key);
  }
});

Возможно использование более простых/более коротких путей с использованием простого Underscore.


В случае, если кто-то здесь использует Lodash вместо Underscore, также возможно, что очень короткое и легко читаемое:

var keys = _.invert(obj, true)[ "true" ];

Ответ 2

Гиорги Канделаки дал хороший ответ, но у него были некоторые потенциальные проблемы (см. мой комментарий к его ответу).

Правильный способ:

_(obj).pairs().filter(_.last).map(_.first)

или

_.map(_.filter(_.pairs(obj),_.last),_.first)

Ответ 3

var data = {1: false, 2: true, 3: false, 4: true};

var filteredIds = _.filter(_.keys(data), function (key) {
    return data[key];
});

// result [2, 4]


var rejectedIds = _.reject(_.keys(data), function (key) {
    return data[key];
});

// result [1, 3]

Ответ 4

Вы можете использовать _.pick. Вот так:

var data = {1: false, 2: true, 3: false, 4: false, 5: false, 6: false, 7: false, 8: true, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false}

var keys = _.keys(_.pick(data, function(value) {
  return value;
}));

Ответ 5

Вы можете попробовать следующее:

_.pairs(obj)
 .filter(function(pair) { return pair[1] })
 .map(function(pair) { return pair[0] })

Или же, но бит более краткий:

_.pairs(obj).filter(_.last).map(_.first)

Ответ 6

var obj = {1: false, 2: true /*...*/};

вы можете использовать сокращение:

_(obj).reduce(function(memo, val, key){
    if (val)
        memo.push(key);
    return memo;
}, []);

или карту цепи:

_(obj).chain().map(function(val, key){
    if (val)
        return key;
}).reject(_.isUndefined).value();

Ответ 7

Вы можете сделать это очень легко

var obj = { a: false, b: false, c: true, d: false, e: true, f: false };
    name, names;

name = _.findKey(obj, true);
// -> 'c'
names = _.findKeys(obj, true);
// -> ['c', 'e']

Для этого вам просто нужно немного подчеркнуть подчеркивание:

_.mixin({

  findKey: function(obj, search, context) {
    var result,
        isFunction = _.isFunction(search);

    _.any(obj, function (value, key) {
      var match = isFunction ? search.call(context, value, key, obj) : (value === search);
      if (match) {
        result = key;
        return true;
      }
    });

    return result;
  },

  findKeys: function(obj, search, context) {
    var result = [],
        isFunction = _.isFunction(search);

    _.each(obj, function (value, key) {
      var match = isFunction ? search.call(context, value, key, obj) : (value === search);
      if (match) {
        result.push(key);
      }
    });

    return result;
  }
});

И вы можете использовать функцию как фильтр, например:

var team = {
  place1: { name: 'john', age: 15 },
  place2: { name: 'tim', age: 21 },
  place3: { name: 'jamie', age: 31 },
  place4: { name: 'dave', age: 17 }}

// Determine the places of players who are major
var placeNames = _.findKeys(team, function(value) { return value.age >= 18; });
// -> ['place2', 'place3']

Наслаждайтесь; -)

Ответ 8

Моя версия:

var list = {
    1: false, 2: true, 3: false, 4: false,
    5: false, 6: false, 7: false, 8: true,
    12: false, 13: false, 14: false, 15: false,
    16: false, 17: false, 18: false, 19: false
};

_.chain(list).map(function(val, key) {
    return val ? parseInt(key) : undefined
}).reject(function(val) {
    return _.isUndefined(val);
}).value();
// returns [2,8]

Ответ 9

Это может быть проще

result = _.chain(obj)
    .map(function(value, key){
        return value?key:false;
    })
    .filter(function(v){
        return v
    })
    .value();

Ответ 10

function findKey(obj, value){
    var key;

    _.each(_.keys(obj), function(k){
      var v = obj[k];
      if (v === value){
        key = k;
      }
    });

    return key;
}

Ответ 11

Другое потенциальное решение:

// Your example data
var data = {1: false, 2: true, 3: false, 4: false, 5: false, 6: false, 7: false, 8: true, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false};

// Outputs the keys: ["2", "8"]
_.keys(_.transform(data, function(r, v, k) { v ? r[k] = 1 : null; }));

// Outputs the keys as integers: [2, 8]
_.map(_.keys(_.transform(data, function(r, v, k) { v ? r[k] = 1 : null; })), _.parseInt)

Итак, в основном:

  • Преобразовать исходный объект, чтобы вырезать ложнозначные ключи
  • Возьмите список ключей из преобразованного результата
  • Преобразуйте ключи в int, если вам нужно

Ответ 12

Я использую этот: Извлеките все ключи с тем же значением из объекта (а не только объект с только логическими значениями) с помощью lodash

function allKeys(obj, value) {
  _.keys(_.pick(obj, function (v, k) { return v === value; }));
}

Пример:

var o = {a: 3, b: 5, c: 3};
var desiredKeys = allKeys(o, 3);
// => [a, c]

Ответ 13

Это способ сделать это без использования каких-либо библиотек в ES6

let z = {2: true, 3:false, 8:true, 9:false, 10: false}
Array.from(new Set(Object.keys(z).map(function(k){if(z[k]){return k}}))).filter(f=>f)

и вы получите [2, 8]

Ответ 14

Я не знаю underscore.js. Но, используя обычный JS, я написал код ниже.

function myFunction()
{
var str="1: false; 2: true; 3: false; 4: false; 5: false; 6: false; 7: false; 9: true; 12: false";
var n=str.split(";");

for(var i=0;i<n.length;i++)
{
     if(n[i].search("true")!=-1){
     alert(n[i].slice(0,n[i].search(":")));
     }
}