简体   繁体   English

在数组元素之间插入对象的最优雅的方法是什么?

[英]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]

Update更新

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); }

Immutable solution不可变的解决方案

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']

Use ES6 flatMap function.使用 ES6 flatMap函数。

const insertBetween = (ele, array) => {
  return array.flatMap((x) => [ele, x]).slice(1);
};

insertBetween('+', [1, 2, 3]);

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.

相关问题 插入此条件语句的最优雅方式是什么? - What is the most elegant way to insert this conditional statement? 什么是读取对象数组的所有元素的属性的更优雅方式 - What is a more elegant way of reading a property of all elements of an array of objects 使这种字符串数组更改的最优雅的方法是什么? - What is the most elegant way to make this kind of string array change? 通过其他数组过滤数组的最优雅方法 - Most elegant way to filter array by other array 返回 javascript 中 2 个对象之间的匹配元素数组的最高效方法是什么? - What is the most performant approach to return an array of matching elements between 2 objects in javascript? 根据对象数组中的值对 DOM 元素进行排序的最有效方法是什么? - What is the most efficient way to sort DOM elements based on values in an array of objects? 当声明具有多个级别的多个javascript对象时,最优雅的方法是什么? - When declar multiple javascript objects with more than one levels, what is the most elegant way? 如何以最优雅的方式从javascript中的对象数组中获取最大值? - How to get the largest value from array of objects in javascript, in the most elegant way? 在 Javascript 中应用多个改变相同数组的函数的最优雅方法是什么? - What is the most elegant way to apply multiple functions that mutates the same array in Javascript? 在Javascript中,将数组的最后一个元素引入开头的最紧凑,优雅和高效的方法是什么? - In Javascript, what is the most compact, elegant and efficent way to bring the last element of an array to the beginning?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM