[英]What is the most elegant way to insert objects between array elements?
I'm sure there are many ways to achieve that but I'm looking for something "elegant".我确信有很多方法可以实现这一目标,但我正在寻找“优雅”的东西。
a = [
'a',
'b',
'c'
];
magicArrayJoin(a, {value: 255} ); // insert the same object between each item
result == [
'a',
{value: 255},
'b',
{value: 255}
'c'
];
All proposals are welcome.欢迎所有建议。 :)
:)
You can do it with flatMap.你可以用 flatMap 来做到这一点。 It can be found from lodash for example
例如,它可以从lodash 中找到
_.flatMap([1,2,3,4], (value, index, array) =>
array.length -1 !== index // check for the last item
? [value, "s"]
: value
);
ouputs输出
[1, "s", 2, "s", 3, "s", 4]
Array#flatMap proposal is in the works so in future this should work: Array#flatMap 提案正在制定中,因此将来应该可以:
[1, 2, 3, 4].flatMap(
(value, index, array) =>
array.length - 1 !== index // check for the last item
? [value, "s"]
: value,
);
One-liner using plain ES6:使用普通 ES6 的单行:
const interleave = (arr, thing) => [].concat(...arr.map(n => [n, thing])).slice(0, -1)
Usage:用法:
interleave(['foo', 'bar', 'baz'], 'avocado')
Prints:印刷:
> ["foo", "avocado", "bar", "avocado", "baz"]
In my opinion the most elegant way to do this is the following one:在我看来,最优雅的方法是以下一种:
ES6 syntax version ES6 语法版本
const insertIntoArray = (arr, value) => {
return arr.reduce((result, element, index, array) => {
result.push(element);
if (index < array.length - 1) {
result.push(value);
}
return result;
}, []);
};
Usage:用法:
insertIntoArray([1, 2, 3], 'x'); // => [1, 'x', 2, 'x', 3]
An ordinary loop seems to be the best:一个普通的循环似乎是最好的:
function intersperse(arr, el) {
var res = [], i=0;
if (i < arr.length)
res.push(arr[i++]);
while (i < arr.length)
res.push(el, arr[i++]);
return res;
}
If you're looking for something elegant, it would probably have to use some kind of concatMap
, as in如果您正在寻找优雅的东西,则可能必须使用某种
concatMap
,如
function concatMap(arr, fn) { return [].concat.apply([], arr.map(fn)); }
function intersperse(arr, el) { return concatMap(arr, x => [el, x]).slice(1); }
When reducing an array the reduce function should not mutate the array but return a new value (in this case a new array).当减少一个数组时,reduce 函数不应该改变数组而是返回一个新值(在这种情况下是一个新数组)。 That way the changes will be only applied to the returned array and not the original one and side effects will be avoided.
这样,更改将只应用于返回的数组,而不是原始数组,并且可以避免副作用。
const insertBetween = (insertee, array) => array.reduce(
(acc, item, i, { length }) => {
if (i && i < length) {
return [...acc, insertee, item];
}
return [...acc, item];
},
[]
);
Ramda has intersperse method that: Ramda有散布方法:
Creates a new list with the separator interposed between elements.
创建一个新列表,在元素之间插入分隔符。
Code:代码:
R.intersperse({name: 'separator'}, ['one', 'two', 'three']);
Result:结果:
[
'one',
{name: 'separator'},
'two',
{name: 'separator'},
'three'
]
You can achieve this using reduce (it is also immutable).您可以使用 reduce(它也是不可变的)来实现这一点。
const insertBetween = (insertion, array) => array.reduce( (newArray, member, i, array) => i < array.length - 1 ? newArray.concat(member, insertion) : newArray.concat(member), [] ); const result = insertBetween('and', [1, 2, 3]); console.log(result); // outputs; // [ // 1, // 'and', // 2, // 'and', // 3 // ]
Or in older JS syntax;或者使用较旧的 JS 语法;
function insertBetween(insertion, array) { const indexOfLastItem = array.length - 1; return array.reduce(withInsertion, []); function withInsertion(newArray, item, index, array) { return index < indexOfLastItem ? newArray.concat(item, insertion) : newArray.concat(item); } } const result = insertBetween('and', [1, 2, 3]); console.log(result); // outputs; // [ // 1, // 'and', // 2, // 'and', // 3 // ]
function insertObject(arr, obj) {
var result = [];
function insert(element, index) {
result.push(element);
if (index + 1 < arr.length) {
result.push(obj);
}
}
arr.forEach(insert);
return result;
}
var a = [1, 2, 3, 4];
insertObject(a, {
test: 'test'
});
Using splice as Kamen suggests, you could do something like:按照 Kamen 的建议使用 splice,您可以执行以下操作:
const numSeparators = arr.length - 1;
for (let i = 1; i <= numSeparators; i++) {
const index = (i * 2) - 1;
arr.splice(index, 0, { value: 255 });
}
for a simple purely functional way I suggest doing it this way:对于简单的纯功能方式,我建议这样做:
const magicArrayJoin = (array, el) =>
array.length ?
array.slice(1).reduce((acc, cur) => acc.concat([el, cur]), [array[0]]) :
[]
pn this way is not the most performant one in javascript pn 这种方式不是 javascript 中性能最好的方式
const fruits = ['orange', 'apple', 'lemon', 'banana'];
const newFruits = [...fruits.slice(0, 1), 'strawberry', ...fruits.slice(3)];
// = ['orange', 'strawberry', 'banana']
ES6:
const arrayWithSeparator = array.reduce((a, i) => a.length ? a.push(separator) && a.push(i) && a : a.push(u) && a, [])
Array.splice()
should do the job like so: Array.splice()
应该像这样完成工作:
a.splice(1, 0, {value : 255})
The first argument is the position at which you want to delete or insert elements, the second is the delete count, the third (optional) is the new element[s] you want to insert.第一个参数是您要删除或插入元素的位置,第二个是删除计数,第三个(可选)是您要插入的新元素[s]。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.