如何在 Javascript 中切片对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39336556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I slice an object in Javascript?
提问by JC Garcia
I was trying to slice an object using Array.prototype, but it returns an empty array, is there any method to slice objects besides passing arguments or is just my code that has something wrong? Thx!!
我试图使用 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);
采纳答案by Bergi
I was trying to slice an object using
Array.prototype
, but it returns an empty array
我试图使用 切片对象
Array.prototype
,但它返回一个空数组
That's because it doesn't have a .length
property. It will try to access it, get undefined
, cast it to a number, get 0
, and slice at most that many properties out of the object. To achieve the desired result, you therefore have to assign it a length
, or iterator through the object manually:
那是因为它没有.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);
回答by trad
Nobody mentioned Object.entries()yet, which might be the most flexible way to do it. This method uses the same ordering as for..in
when enumerating properties, i.e. the order that properties were originally entered in the object. You also get subarrays with both property and value so you can use whichever or both. Finally you don't have to worry about the properties being numerical or setting an extra length property (as you do when using Array.prototype.slice.call()
).
Here's an example:
还没有人提到Object.entries(),这可能是最灵活的方法。此方法使用与for..in
枚举属性时相同的顺序,即属性最初输入到对象中的顺序。您还可以获得具有属性和值的子数组,因此您可以使用其中一个或两者。最后,您不必担心属性是数字或设置额外的长度属性(就像使用 时所做的那样Array.prototype.slice.call()
)。
下面是一个例子:
const obj = {'prop1': 'foo', 'prop2': 'bar', 'prop3': 'baz', 'prop4': {'prop': 'buzz'}};
You want to slice the first two values:
您想对前两个值进行切片:
Object.entries(obj).slice(0,2).map(entry => entry[1]);
//["foo", "bar"]
All of the keys?
所有的钥匙?
Object.entries(obj).slice(0).map(entry => entry[0]);
//["prop1", "prop2", "prop3", "prop4"]
The last key-value pair?
最后一个键值对?
Object.entries(obj).slice(-1)
//[ ['prop4', {'prop': 'buzz'}] ]
回答by Amerzilla
You can reduce
the result of Object.keys
function
你可以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);
回答by rekinyz
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' } ]
[{'0':'零'},{'1':'一个'}]
回答by Mikhail Lipilin
I think it can helps you:
我认为它可以帮助您:
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);
回答by Ted Hopp
Try adding a 'length' property to my_object
and then your code should work:
尝试添加一个“长度”属性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);
回答by Kevin Gilbert
The best modern solution to this is the combination of Object.fromEntriesand Object.entries.
对此最好的现代解决方案是Object.fromEntries和Object.entries的组合。
const foo = {
one: 'ONE',
two: 'TWO',
three: 'THRE',
four: 'FOUR',
}
const sliced = Object.fromEntries(
Object.entries(foo).slice(1, 3)
)
console.log(sliced)
回答by Redu
You can't unless it has a [Symbol.iterator]
generator function andlength
property exists. Such as;
你不能,除非它有一个[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);
回答by jishi
You don't mention it in your question, but that looks awfully a lot like an arguments object.
你没有在你的问题中提到它,但这看起来非常像一个 arguments 对象。
Convert it to an array using Array.from()
then use it like any other array. As long as it is an enumerable object.
使用将其转换为数组,Array.from()
然后像任何其他数组一样使用它。只要它是一个可枚举的对象。
For a polyfill for older browsers, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
有关旧浏览器的 polyfill,请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
回答by Karim Temple
// 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' ]