返回没有删除元素的数组?使用splice()而不更改数组?

时间:2011-07-26 03:27:31

标签: javascript arrays

我想做类似的事情:

var myArray = ["one","two","three"];
document.write(myArray.splice(1,1));
document.write(myArray);

首先显示“一,三”,然后是“一,二,三”。我知道splice()返回被删除的元素并更改数组,但是是否有函数返回一个删除了元素的新数组?我试过了:

window.mysplice = function(arr,index,howmany){
    arr.splice(index,howmany);
    return arr;   
};

如果我尝试:

var myArray = ["one","two","three"];
document.write(mySplice(myArray,1,1));
document.write(myArray);

它仍会改变myArray ......

请帮忙。

12 个答案:

答案 0 :(得分:36)

您想要slice

  

返回数组部分的一级深层副本。

所以,如果你

a = ['one', 'two', 'three' ];
b = a.slice(1, 3);

然后a仍然是['one', 'two', 'three']b将是['two', 'three']。注意slice的第二个参数,它比你想要切出的最后一个索引多一个:

  

基于零的索引,用于结束提取。 slice提取但不包括end

答案 1 :(得分:23)

如下面的答案所示,这是一个代码快照

var myArray = ["one","two","three"];
var cloneArray = myArray.slice();

myArray.splice(1,1);

document.write(myArray);       
document.write(cloneArray);

答案 2 :(得分:10)

使用此:

function spliceNoMutate(myArray,indexToRemove) {
    return myArray.slice(0,indexToRemove).concat(myArray.slice(indexToRemove+1));
}

答案 3 :(得分:3)

我知道这个问题已经过时了,但这种方法可能会派上用场。

var myArray = ["one","two","three"];
document.write(myArray.filter(function(v, index) { return index !== 1 })

var myArray = ["one","two","three"];
document.write(myArray.filter(function(v, index) { return v !== "two" })

这使用Array.filter()函数并针对索引为1或值为" 2"进行测试。

<小时/> 现在,我不能保证这些解决方案的性能(因为它检查阵列上的每个项目,Nguyen answer可能更有效率),但如果你想做更多的事情,它会更灵活复杂的东西,确保更容易理解。

答案 4 :(得分:3)

您可以使用ES6传播功能:

let myArray = ['one','two','three'];
let mySplicedArray = [...myArray];
mySplicedArray.splice(1,1); 

console.log(myArray); /// ['one', 'two', 'three']
console.log(mySplicedArray); /// ['one', 'three']

答案 5 :(得分:0)

而不是:

document.write(myArray.splice(1,1));

为什么不直接使用:

document.write(myArray[1]);

splice()按定义修改数组。如果您需要副本,请参阅slice()

答案 6 :(得分:0)

为什么不直接引用索引?

var myArray = ["one","two","three"];
document.write(myArray[1] + '<br />');
document.write(myArray);

示例:http://jsfiddle.net/AlienWebguy/dHTUj/

答案 7 :(得分:0)

我认为从数组中拼接元素而不进行变异且不复制自身的最佳方法是使用过滤器:

arr = ["one", "two", "three"]
elToRemove = "two"
filteredArr = arr.filter( n => n != elToRemove)

console.log(arr) // ["one", "two", "three"]
console.log(filteredArr) // ["one", "three"]

答案 8 :(得分:0)

我认为最巧妙的方法是创建一个简单的函数,如果需要全局访问,则将该函数绑定到Array原型。

提供给该问题的大多数答案都是错误的。人们对返回一个数组的一个元素而不修改其内容感到困惑,但是OP所需要的是返回一个数组的克隆而没有一个元素。

这是我的解决方案:

let arr = ['one', 'two', 'three'];

/* functional */
window.cloneSlice = (arr, start, end) => {
  const _arr = arr.slice();
  _arr.splice(start, end);
  return _arr;
}
// usage
console.log(cloneSlice(arr, 1, 1)); // one, three
console.log(arr); // one, two, three

/* prototyped */
Array.prototype.cloneSlice = function (start, end) { return cloneSlice(this, start, end) }
// usage
console.log(arr.cloneSlice(1, 1)); // one, three
console.log(arr); // one, two, three

答案 9 :(得分:0)

const getSubArr = (arr, start, end) => {
    return end > start
        ? arr.filter((_, i) => i >= start && i < end)
        : arr.filter((_, i) => i >= start || i < end);
};

此函数返回一个数组,该数组是原始数组的序列。它的优点是它可以用于获取子数组,而无需在原始数组中间放置序列。

const chars = ["a", "b", "c", "d", "e", "f"];
console.log(getArrInRange(chars, 2, 4));
console.log(getArrInRange(chars, 4, 2));

答案 10 :(得分:0)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

const abc = ['aaa', 'bbb', 'ccc']
const ac = abc.filter(_ => _ !== 'bbb')

您想这样做,这样就拥有一个非突变数组。

我认为性能不如slice + concat那样好,但是担心会成为问题。在此之前,filter真的很干净。

答案 11 :(得分:0)

            <xsl:for-each select="//item[position() mod 4 = 0 and contains(@name, 'Point')]">
            <tr>
                <td>
                    <xsl:value-of select="position()"/>
                </td>
                <td>
                    <xsl:value-of select="format-number(@value, '0.00')"/>
                </td>
                <td>
                    <xsl:value-of select="following-sibling::item[contains(@name, 'Value2')]/@value"/>
                </td>
                <td>
                    <xsl:value-of select="following-sibling::item[contains(@name, 'Value3')]/@value"/>
                </td>
                <td>
                    <xsl:value-of select="@name"/>
                </td>
            </tr>
            </xsl:for-each>