it-swarm.com.ru

Как я могу нарезать объект в Javascript?

Я пытался нарезать объект с помощью Array.prototype, но он возвращает пустой массив. Есть ли какой-либо метод для нарезки объектов, кроме передачи аргументов, или просто в моем коде что-то не так? Спасибо!!

var my_object = {
 0: 'zero',
 1: 'one',
 2: 'two',
 3: 'three',
 4: 'four'
};

var sliced = Array.prototype.slice.call(my_object, 4);
console.log(sliced);
11
JC Garcia

Я пытался нарезать объект с помощью Array.prototype, но он возвращает пустой массив

Это потому, что у него нет свойства .length. Он попытается получить к нему доступ, получить undefined, привести его к числу, получить 0 и выделить максимум столько свойств объекта. Поэтому для достижения желаемого результата вы должны назначить ему length или итератор объекта вручную:

var my_object = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'};

my_object.length = 5;
console.log(Array.prototype.slice.call(my_object, 4));

var sliced = [];
for (var i=0; i<4; i++)
    sliced[i] = my_object[i];
console.log(sliced);
8
Bergi

Никто еще не упомянул Object.entries () , что может быть наиболее гибким способом сделать это. Этот метод использует тот же порядок, что и for..in, при перечислении свойств, то есть порядок, в котором свойства были изначально введены в объект. Вы также получаете подмассивы как со свойством, так и со значением, так что вы можете использовать любой из них или оба. Наконец, вам не нужно беспокоиться о том, что свойства являются числовыми или задают свойство дополнительной длины (как вы это делаете при использовании Array.prototype.slice.call()).
Вот пример:

const obj = {'prop1': 'foo', 'prop2': 'bar', 'prop3': 'baz', 'prop4': {'prop': 'buzz'}};

Вы хотите нарезать первые два значения:

Object.entries(obj).slice(0,2).map(entry => entry[1]);
//["foo", "bar"]

Все ключи?

Object.entries(obj).slice(0).map(entry => entry[0]);
//["prop1", "prop2", "prop3", "prop4"]

Последняя пара ключ-значение?

Object.entries(obj).slice(-1)
//[ ['prop4', {'prop': 'buzz'}] ]
25
trad
var obj = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'};
var result = Object.keys(obj).slice(0,2).map(key => ({[key]:obj[key]}));

console.log(result);

[{'0': 'zero'}, {'1': 'one'}]

3
rekinyz

Вы можете reduce результат функции Object.keys 

const myObject = {
 0: 'zero',
 1: 'one',
 2: 'two',
 3: 'three',
 4: 'four'
};

const sliced = Object.keys(myObject).slice(0, 2).reduce((result, key) => {
                    result[key] = myObject[key];

                    return result;
                }, {});

console.log(sliced);

2
Amerzilla

Я думаю, что это может помочь вам:

var my_object = { 0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four' };

var sliced = Object.keys(my_object).map(function(key) { return my_object[key] }).slice(4);

console.log(sliced);
1
Mikhail Lipilin

Попробуйте добавить свойство length в my_object, и тогда ваш код должен работать:

    var my_object = {
     0: 'zero',
     1: 'one',
     2: 'two',
     3: 'three',
     4: 'four',
     length: 5
    };
    
    var sliced = Array.prototype.slice.call(my_object, 4);
    console.log(sliced);

1
Ted Hopp

// Works, but acts weird when things get serious
// Avoids screwing with the properties of my_object
// You don't get Object.create() until ES5.1
function lazySlice(obj, idx) {
  var newObj = Object.create(obj, { length: {value: Object.keys(obj).length} }),
  idx = idx || 0;

  return Array.prototype.slice.call(newObj, idx);
}

// Only gives you own enumerable properties with keys "0" to n
// Preserves element order (based on key number)
// Ignores non-numbered keys
// You don't get Object.keys() until ES5
function enumSlice(obj, idx) {
  var arr = [], 
    keys = Object.keys(obj),
    idx = idx || 0;

  for (var i = 0; i <= keys.length - 1; i++)
    if (keys[i] >= idx && keys[i] % 1 === 0 && keys[i] >= 0 && keys[i].indexOf('e') < 0) 
      arr.Push(obj[keys[i]]);

  return arr;
}

var my_object = {
  0: 'zero',
  1: 'one',
  2: 'two',
  3: 'three',
  4: 'four'
}; 
console.log(lazySlice(my_object, 3));      // [ 'three', 'four' ]
console.log(enumSlice(my_object, 3));      // [ 'three', 'four' ]

var mixed_object = {
   "9": 'nine',
   "2": 'two',
   "1": 'one',
   "7": 'seven',
   "7.5": 'seven point five',
   "1e4": 'sneaky',
   "-4": 'negative four',
   "0": 'zero',
   "length": 35
};
console.log(lazySlice(mixed_object));      // [ 'zero', 'one', 'two', , , , , 'seven',  ]
console.log(enumSlice(mixed_object));      // [ 'zero', 'one', 'two', 'seven', 'nine' ]

0
Karim Temple

Вы не можете, если у него нет [Symbol.iterator] функция генератора и Свойство length существует. Такие как;

var my_object = { 0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', length:5 },
       sliced;

my_object[Symbol.iterator] = function* (){
                                          var oks = Object.keys(this);
                                          for (var key of oks) yield this[key];
                                         };

sliced = Array.prototype.slice.call(my_object, 2);
console.log(sliced);

0
Redu

Вы не упоминаете об этом в своем вопросе, но это очень похоже на объект аргументов. 

Преобразуйте его в массив, используя Array.from(), затем используйте его, как и любой другой массив. Пока это перечислимый объект.

Полифайл для старых браузеров см. В https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

0
jishi