导航
方法 | 作用 | 是否影响原数组 |
---|---|---|
push | 在数组后添加元素,返回长度 | ✅ |
unshift | 数组开头添加元素,返回长度 | ✅ |
pop | 删除数组最后一项,返回被删项 | ✅ |
shift | 删除数组第一项,返回被删项 | ✅ |
reserve | 反转数组,返回数组 | ✅ |
sort | 排序数组,返回数组 | ✅ |
splice | 截取数组,返回被截取部分 | ✅ |
join | 将数组变字符串,返回字符串 | ❌ |
concat | 连接数组 | ❌ |
map | 相同规则处理数组项,返回新数组 | ❌ |
forEach | 遍历数组 | ❌ |
filter | 过滤数组项,返回符合条件的数组 | ❌ |
every | 每一项符合规则才返回true | ❌ |
some | 只要有一项符合规则就返回true | ❌ |
reduce | 接受上一个return和数组下一项 | ❌ |
flat | 数组扁平化 | ❌ |
slice | 截取数组,返回被截取区间 | ❌ |
function getItemById(arr, id) {
var item = null;
try {
arr.forEach(function (curItem, i) {
console.log(i)
if (curItem.id == id) {
item = curItem;
throw Error();
}
})
} catch (e) {}
return item;
}
var arr = [12, 1, 24, -123, 12123123];
arr.length = 0;
// arr.splice(0, arr.length);
// 通过将空数组 [] 赋值给数组(严格意义来说这只是将ary重新赋值为空数组,
// 之前的数组如果没有引用在指向它将等待垃圾回收。)
// arr = [];
console.log(arr);
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 随机交换数组内的元素 ✅
function result(arr) {
for (let i = 0; i < arr.length; i++) {
// 随机索引【Math.random()返回一个浮点, 伪随机数在范围[0,1)】
let randomIndex = parseInt(Math.random() * arr.length);
// 存下当前正常索引值对应的数字
let curNum = arr[i];
// 将其重新赋值为随机索引对应的数字
arr[i] = arr[randomIndex];
// 将随机索引对应的数字替换为当前正常索引值对应的数字
arr[randomIndex] = curNum;
}
return arr;
}
// sort()可以调用一个函数做为参数,如果这个函数返回的值为负数表示数组中的a项排在b项前
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(() => Math.random() - 0.5)
console.log(arr);
const array = [ '2', 'b', '9','a','7','3','4','b','6', '4' ];
function handle(arr) {
// ...your code
}
handle(array); // output: ['2', '3', '4', '6', '7', '9', 'a', 'b']
const array = [ '2', 'b', '9','a','7','3','4','b','6', '4' ];
function handle(arr) {
return Array.from(new Set(arr))
.sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0));
}
console.log(handle(array)); // output: ['2', '3', '4', '6', '7', '9', 'a', 'b']
var arr = [1, 2, 3];
Array.prototype.myUnshift = function() {
// 在数组打头,添加一个或多个元素,最后返回最新数组的长度
var len = arguments.length;
for (let i = len - 1; i >= 0; i--) {
const element = arguments[i];
this.splice(0, 0, element);
}
return this.length;
}
// console.log(arr.unshift(3, 2, 1), arr);
console.log(arr.myUnshift(3), arr);
var arr = [1, 2, 3];
Array.prototype.myUnshift = function() {
var pos = 0;
for (let i = 0; i < arguments.length; i++) {
const element = arguments[i];
this.splice(pos, 0, element);
pos++;
}
return this.length;
}
// console.log(arr.unshift(3, 2, 1), arr);
console.log(arr.myUnshift(3, 2, 1), arr);
var arr = ['Are you OK', 'Lance', 'Jerry', '我爱你'];
// unicode 0-255 1个字节;256 2个字节
var getBytes = function(str) {
// 先把每个字符都当一个字节算
var bytes = str.length;
for (var i = 0; i < str.length; i++) {
if (str.charCodeAt(i) > 255) {
bytes++;
}
}
return bytes;
}
arr.sort(function(a, b) {
return getBytes(a) - getBytes(b);
});
// 结果: [ 'Lance', 'Jerry', '我爱你', 'Are you OK' ]
1. 循环 通过 hasOwnProperty 判断新数组是否有该属性(问题:{} 会被解析成'[object Object]')
var arr = [
{}, {},
'', '',
233, 233, '233',
'abc',
undefined,
null, null,
NaN, NaN,
123,
[2], [2],
[2, 3]
];
Array.prototype.myUnique = function() {
var hash = {},
newArr = [];
for (var i = 0; i < this.length; i++) {
var item = this[i];
if (!hash.hasOwnProperty(typeof item + JSON.stringify(item))) {
hash[typeof item + JSON.stringify(item)] = item;
newArr.push(item);
}
}
return newArr;
};
console.log(arr.myUnique());
// [
// {}, '',
// 233, '233',
// 'abc', undefined,
// null, NaN,
// 123, [ 2 ],
// [ 2, 3 ]
// ]
2. ES6 Set
Array.prototype.myUnique = function() {
return Array.from(new Set(this));
};
// [
// {}, {},
// '', 233,
// '233', 'abc',
// undefined, null,
// NaN, 123,
// [ 2 ], [ 2 ],
// [ 2, 3 ]
// ]
3. 利用includes检测数组是否有某个值 或者indexOf判断索引
Array.prototype.myUnique = function() {
let arr = [];
for (let i = 0; i < this.length; i++) {
if (!arr.includes(this[i])) {
arr.push(this[i]);
}
}
return arr;
};
// [
// {}, {},
// '', 233,
// '233', 'abc',
// undefined, null,
// NaN, 123,
// [ 2 ], [ 2 ],
// [ 2, 3 ]
// ]
4. Map
Array.prototype.myUnique = function() {
let map = new Map(), arr = [];
for (let i = 0; i < this.length; i++) {
if (!map.has(this[i])) {
map.set(this[i], this[i]);
arr.push(this[i]);
}
}
return arr;
}
// [
// {}, {},
// '', 233,
// '233', 'abc',
// undefined, null,
// NaN, 123,
// [ 2 ], [ 2 ],
// [ 2, 3 ]
// ]
5. filter (问题:无法识别NaN)
Array.prototype.myUnique = function() {
return this.filter((v, idx) => {
return this.indexOf(v, 0) === idx;
});
}
// [
// {}, {},
// '', 233,
// '233', 'abc',
// undefined, null,
// 123, [ 2 ],
// [ 2 ], [ 2, 3 ]
// ]
var arr = [10,5,11,7,8,9]; // 11-5=6
function getMaxProfit(arr) {
var min = max = arr[0];
for(var i = 0; i < arr.length; i++) {
min = min <= arr[i] ? min : arr[i];
max = max >= arr[i] ? max : arr[i];
}
return Math.abs(max - min);
}
// 若 nums = [1,1,2], 则函数应返回长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
// 若 nums = [0,0,1,1,1,2,2,3,3,4], 则返回 5, 并且原数组被修改为 0, 1, 2, 3, 4。
var nums = [0,0,1,1,1,2,2,3,3,4];
function removeDuplicates(arr) {
let len = arr.length;
for (let i = 0; i < len; i++) {
if (arr[i] === arr[i + 1]) {
arr.splice(i, 1);
i--;
len--;
}
}
return arr;
}
console.log(removeDuplicates(nums));
var arr = [1, 1, 2, 1, 10, 10, 11, 1, 7];
function fn(arr) {
let hash = {};
arr.forEach((v, idx) => {
if (!hash[v]) {
hash[v] = {
target: v,
idxs: [idx]
}
} else {
hash[v].idxs.push(idx);
}
});
let count = 0, ret = null;
Object.values(hash).forEach(v => {
if (v.idxs.length > count) {
ret = v;
count = v.idxs.length;
}
});
return ret;
}
console.log(fn(arr));
已知如下数组:
var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
// ES6
// 扁平化数组
Array.prototype.flat = function() {
return [].concat(...this.map(item => Array.isArray(item) ? item.flat() : [item]))
}
// 数组去重
Array.prototype.unique = function() {
return [...new Set(this)]
}
// 数组排序
const sort = (a, b) => a - b;
console.log(arr.flat().unique().sort(sort));
// ES5
Array.prototype.flat = function() {
return this.toString().split(',').map(v => Number(v));
}
Array.prototype.unique = function() {
var obj = {}
return this.filter((item, index) => {
var tempItem = typeof item + JSON.stringify(item)
return obj.hasOwnProperty(tempItem) ?
false :
obj[tempItem] = true
})
}
const sort = (a, b) => a - b;
console.log(arr.flat().unique().sort(sort));
// ES5 或者
Array.prototype.flat = function() {
return this.toString().split(',').map(v => Number(v));
}
function flat(arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
if (item instanceof Array) {
result.splice(result.length, 0, ...flat(item));
} else {
result.push(item);
}
}
return result;
}
const sort = (a, b) => a - b;
console.log(flat(arr).unique().sort(sort));
迭代
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
const flatten = function(arr) {
while (arr.some(v => Array.isArray(v))) {
arr = [].concat(...arr)
}
return arr
}
console.log(flatten(arr));
递归
const flatten = function(arr) {
return [].concat(...arr.map(v => Array.isArray(v) ? flatten(v) : v));
}
console.log(flatten(arr));
字符串拼接
function flatten(arr) {
return arr.join(',').split(',').map(v => Number(v))
}
给你一个整数数组 prices
,其中 prices[i]
表示某支股票第 i
天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。
最大总利润为 4 + 3 = 7 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
最大总利润为 4 。
示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0。
var arr = [7, 1, 5, 3, 6, 4]
function maxProfit(arr) {
var income = 0;
for (var i = 0, len = arr.length; i < len; i++) {
var gap = arr[i + 1] - arr[i]; // 后一个与前一个比较,大于零则赚
if (gap > 0) {
income += gap;
}
}
return income;
}
console.log(maxProfit(arr));
给定一个数组 prices
,它的第 i
个元素 prices[i]
表示一支给定股票第 i
天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0
。
示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
解题思路:
如果第i
天卖出股票,则最大利润为 (该天的股价-前面天数中最小的股价)
,然后与已知的最大利润比较,如果大于则更新当前最大利润的值。
/**
* @param {number[]} prices
* @return {number} [7,3,2,3,1,7]
*/
var maxProfit = function(prices) {
// 初始化: 收益 0
let profit = 0, historyMinCost = prices[0];
for (let i = 1; i < prices.length; i++) {
// 假定当天卖出,与历史最小成本比较,算出当前最大收益
// 再和历史最大收益比较
const curProfit = prices[i] - historyMinCost;
if (curProfit > profit) {
profit = curProfit;
}
if (prices[i] < historyMinCost) {
historyMinCost = prices[i];
}
}
return profit;
};
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
let arr = [1, 2, 3, 4, 5, 6, 7];
function rotate(arr, k) {
for (let i = 0; i < k; i++) {
let temp = arr.pop()
arr.unshift(temp)
}
return arr;
}
console.log(rotate(arr, 3));
// 首先我们研究例子不难发现数组轮转k次实际上是将后k位数字移到了前面,而当k大于数组长度时,
// 我们只需要将k对数组长度取余即可,因为数组每进行了nums.length次轮转后又变回了原样
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function (nums, k) {
if (nums.length === 1) return;
k = k % nums.length;
const temp = nums.splice(nums.length - k, k);
nums.unshift(...temp);
return nums;
};
let arr = [1, 2, 3, 4, 5, 6, 7];
console.log(rotate(arr, 3));
输入: [1,2,3,1] 输出: true
输入: [1,2,3,4] 输出: false
var arr = [1, 2, 3, 1]
function containsDuplicate(arr) {
var obj = {}
for (var i = 0, len = arr.length; i < len; i++) {
if (obj[arr[i]]) {
return true
} else {
obj[arr[i]] = true
}
}
return false
}
// or
function containsDuplicate(arr) {
return [...new Set(arr)].length !== arr.length
}
console.log(containsDuplicate(arr))
var arr = [4, 1, 2, 1, 2]
var arr = [4, 1, 2, 1, 2]
function singleNumber(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) === arr.lastIndexOf(arr[i])) {
return arr[i];
}
}
return -1;
}
console.log(singleNumber(arr));
// or
function singleNumber(arr) {
const a = [...new Set(arr)].reduce((total, cur) => total + cur, 0)
const b = arr.reduce((total, cur) => total + cur, 0)
return 2 * a - b
}
console.log(singleNumber(arr))
var nums1 = [1, 2, 3, NaN, {}]
var nums2 = [2, 2, 8, 10, NaN, {}]
// 方法1:filter + indexOf(不支持 NaN 和 {})
function intersect(nums1, nums2) {
return nums1.filter(v => {
const index = nums2.indexOf(v)
if (index > -1) {
nums2.splice(index, 1)
return v
}
})
}
console.log(intersect(nums1, nums2))
// 方法2:filter + indexOf(支持 NaN,不支持 {})
function intersect(nums1, nums2) {
const aHasNaN = nums1.some(v => isNaN(v))
const bHasNaN = nums2.some(v => isNaN(v))
return nums1.filter(v => {
const index = nums2.indexOf(v)
if (index > -1) {
nums2.splice(index, 1)
return v
}
}).concat(aHasNaN && bHasNaN ? [NaN] : [])
}
console.log(intersect(nums1, nums2))
// 方法3:哈希表(支持 NaN,{})
function intersect(nums1, nums2) {
const map = {}
const res = []
for (let n of nums1) {
if (map[n]) {
map[n]++
} else {
map[n] = 1
}
}
for (let n of nums2) {
if (map[n] > 0) {
res.push(n)
map[n]--
}
}
return res
}
console.log(intersect(nums1, nums2))
// 如果不要求输出一致,则可以用includes
function intersect(nums1, nums2) {
return nums1.filter(v => nums2.includes(v))
}
console.log(intersect(nums1, nums2))
while (count > -1)
var arr = [9, 9, 9] // 预期:[1, 0, 0, 0]
function plusOne(arr) {
var count = arr.length - 1;
// 从末尾往前倒
while (count > -1) {
// 只要当前位+1大于9,就把当前位置为0,count--
if (arr[count] + 1 > 9) {
arr[count] = 0;
count--;
} else {
// 一旦当前位+1不大于9,就放心+1,且直接退出,不用再算更高位的了
arr[count]++;
break;
}
}
// 如果while后,第一位还是0,证明这个数组所有数字都为9.这个时候往数组最前面加个1就好
if (arr[0] === 0) {
arr.unshift(1);
}
return arr;
};
console.log(plusOne(arr))
// or
function plusOne(arr) {
for (let i = arr.length - 1; i >= 0; i--) {
const ele = arr[i];
if (ele + 1 <= 9) {
arr[i]++
break
} else {
arr[i] = 0
}
}
if (arr[0] === 0) {
arr.unshift(1)
}
return arr
}
// or
var arr = [9, 9, 9] // 预期:[1, 0, 0, 0]
function fn(arr) {
let num = parseInt(arr.join('')) + 1;
let str = num.toString();
return str.split('').map(v => Number(v));
}
console.log(fn(arr));
var arr = [0, 1, 0, 3, 12] // 预期:[ 1, 3, 12, 0, 0 ]
var moveZeroes = function (nums) {
// 长度提取出来
var len = nums.length
for (var i = 0; i < len; i++) {
// 从头往后遍历,遇到0则删掉追放到尾部,
// 同时让i--,因为头部删了个0;同时len--,因为不再判断追加后的
if (nums[i] === 0) {
nums.splice(i, 1)
nums.push(0)
i--
len--
}
}
return nums
}
console.log(moveZeroes(arr))
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
给定 var nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
var nums = [2, 7, 11, 15], target = 9
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
const num = nums[i];
// 第二个数索引
const targetIndex = nums.indexOf(target - num);
// 确保存在第二个数,且不为当前遍历的数
if (targetIndex > -1 && targetIndex !== i) {
return [i, targetIndex];
}
}
}
console.log(twoSum(nums, target))
请把两个数组 ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2']
和 ['A', 'B', 'C', 'D']
,合并为 ['A1', 'A2', 'A', 'B1', 'B2', 'B', 'C1', 'C2', 'C', 'D1', 'D2', 'D']
。
考察点:假设有一种情况,让你在一个列表中插入一个广告,不光是数组,对象依然有这种需求,这道题其实就是平常经常需要用到的一个小功能。
let arr1 = ["A1", "A2", "B1", "B2", "C1", "C2", "D1", "D2"]
let arr2 = ["A", "B", "C", "D"]
console.log(
[...arr1, ...arr2].sort((v2, v1) => (
v2.codePointAt(0) - v1.codePointAt(0) ||
v1.length - v2.length ||
v2.codePointAt(1) - v1.codePointAt(1)
))
)