数组的处理方法,感觉需要总结一下了,最近用到的特别多,各种数组之间的处理--持续更新吧

为了案例的综合性,尽量采用对象数组的方式,以及对象数组混合普通数组

1数组去重

// 数组去重,去重指的是重复的只留下一个,而不是全删了
// 这里以数组对象与普通对象为例子
// 并且是以单个数组去重为例子
// 多个数组去重没有必要赘述
// 因为多个数组去重,也不过是数组concat之后,再去重罢了


// 1.new set方式
let arr1 = [{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 1, b: 2 }]
let arr3 = [{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 1, b: 2 }, 'jhjlhjk', 'jhjlhjk', 'sdfdf']
let arr2 = [1, 2, 1]
// console.log([...new Set([...arr2])])
// console.log([...new Set([...arr1])]) //无法去重引用对象类型



// 2.filter方式
// indexof
function filterUnique1(arr) {
  return arr.filter((el, index, self) => {
    return self.indexOf(el, 0) === index//第一个参数:要检索的元素,第二个参数是开始索引的位置
  })
}
// findindex
function filterUnique2(arr) {
  return arr.filter((el, index, self) => {
    return self.findIndex(item => item.b == el.b) === index //找到相同的元素的索引看,是否与这个相同,
    // 同样是一样解释,不过这个函数可以写入回调,可操作性更大一些
  })
}
// 都是一样的解释,由于这里不是正则,不会/g全局匹配,所以只会索引到第一元素
// 于是当出现第二个重复的元素,indexof返回的依然只是第一个重复元素的index
// 而这显然和当前第二个重复元素的index不会相同,就不会返回,就去掉重复元素了

// console.log(filterUnique1(arr1))//  用indexof同样无法去重引用对象类型
// console.log(filterUnique2(arr1))//  可以去重引用对象类型

// 3.普通的双重for循环
// 法1
function forUnique1(arr) {
  let newArr = []
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr.length; j++) {
      if (arr[i].b != arr[j].b) {
        // 如果不相同,并且newArr中没有就push进去
        let flag = newArr.some(el => el.b == arr[j].b)
        !flag ? newArr.push(arr[j]) : ''
      }
    }
  }
  return newArr
}

// console.log(forUnique1(arr1))  //可以去重引用对象类型

// 法2
function forUnique2(arr) {
  arr = arr.concat();
  for (let i = 0, len = arr.length; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (arr[i].b === arr[j].b) {
        arr.splice(j, 1);
        //   splice可以改变数组长度,所以数组长度len和j的下标减一
        len--;
        j--;
      }
    }
  }
  return arr;
}
// console.log(forUnique2(arr1)) //可以去重引用对象类型

// 4.用sort  sort排序对象数组,排序之后就可以放心的比较相邻的,不用担心后面隔着又出现重复的,不同于上一个的就push进数组
function sortUnique(arr) {
  arr = arr.concat().sort((prev, next) => prev.b - next.b) //sort排序对象数组,然后...
  let result = [];
  arr[0] && arr[0] != 0 ? result.push(arr[0]) : ''// result中保存排序后的数组的第一项
  for (let i = 1, len = arr.length; i < len; i++) {
    //   如果相邻两项元素不等,则push进去数组result
    arr[i].b !== arr[i - 1].b && result.push(arr[i]);
  }
  return result;
}
// console.log(sortUnique(arr1)) //可以去重引用对象类型


// 5.for of object
function forOfUnique(arr) {
  arr = arr.concat();
  let result = [];
  let obj = {};

  for (const i of arr) {
    // console.log(i, arr[i], obj)  //原来for of循环 i是每一项....
    // 数组的键是单独的
    // 把arr的值作为obj的键,如果不存在才push进去,存在就不再push进去
    // 不过如果是对象数组,那么不要把对象作为键,而是身上用来标识比较去重的那个属性
    // 我此处是b属性,一般也只会需要一个属性,比如判断id不同的
    // 如果确实有多个属性,那么这种方法就不适合了,因为键只能有一个
    // 那么就用上面的方法呗,能够在if里写多个判断的那种
    if (!obj[i.b]) {
      result.push(i);
      obj[i.b] = 1 //把arr的值作为obj的键,随便赋个值,无影响
    }
  }
  return result;
}
// console.log(forOfUnique(arr1)) //可以去重引用对象类型
// console.log(forOfUnique(arr2))

// 6.reduce
function reduceUnique(arr) {
  arr = arr.concat();
  let result = [];
  let obj = {}
  result = arr.reduce((prev, curv) => {
    if (!obj[curv.b]) {
      prev.push(curv)
      obj[curv.b] = 1 //把arr的值作为obj的键,随便赋个值,无影响
    }
    return prev
  }, [])
  return result
}
console.log(reduceUnique(arr1))  //可以去重引用对象类型
// console.log(reduceUnique(arr2))



// includes 也无法判断引用对象类型(arr1这种),基本就是判断一下普通数组(arr2这种)

//indexOf 第一个参数:要检索的元素,第二个参数是开始索引的位置,也无法判断引用对象类型(arr1这种),基本就是判断一下普通数组(arr2这种)

// findIndex 可以判断查找引用对象类型,为何呢,因为不同于indexof,他可以传回调,可操作空间更大,自然可以判断对象的属性

// reduce   后面加个[]和不加[]的区别
// 基本情况: reduce是个迭代器,prev表示的是上一次遍历的return的结果,curv表示当前遍历的这一项的值
// 如果没加[],那么第一次遍历的时候,prev表示第一项,curv表示第二项,之后是基本情况
// 如果加了[],那么第一次遍历的时候,prev表示这个数组,curv表示第一项,之后是基本情况,注意我此处只放个空数组,实际情况你可以放已经有值的数组等等

// arr = arr.concat().sort((prev, next) => prev.b - next.b) //sort排序对象数组,

// some 有时候里面也写some或者every啥的来判断是否存在

//补充一点,上述数组操作不乏很多for循环判断数组中是否存在这个元素或者是不存在,不过与其用for循环

//不如用map与some,every什么的,语法更加简洁

 

未完待续

 

下次再更

 

 

2.两个数组取出相同部分,得到一个新数组  以及两个数组取出不同部分,得到一个新数组  

暂时先写这几个

let arr1 = [{ a: 1, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 3 }]
let arr2 = [{ a: 1, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 4 }, { a: 1, b: 5 },]
// 一.两个数组取出相同部分,得到一个新数组
// 1.双重for循环

/**
* 获取两个数组的公共部分
*/
function getSameArr(arr1, arr2) {
  let result = []
  let j = 0
  for (let i = 0; i < arr1.length; i++) {
    for (let k = 0; k < arr2.length; k++) {
      if (arr1[i].a === arr2[k].a && arr1[i].b === arr2[k].b) {
        result[j] = arr1[i]
        ++j
      }
    }
  }
  return result
}
console.log(getSameArr(arr1, arr2))

// 2.如果是普通数组而不是对象数组,那就很简单了,方法很多,这里随便举个案例
let result1 = []
let list1 = [1, 2, 3, 4, 5]
let val1 = [1, 2, 3]
result1 = list1.filter(number => val1.includes(number))
console.log(result1)

// 二.两个数组取出不同部分,得到一个新数组
// 1.双重for循环
/**
* 获取两个数组之间的不同的部分
*/
function getdifferentArr(arr1, arr2) {
  let result = []
  let tmp = arr1.concat(arr2)
  let o = {}
  for (let i = 0; i < tmp.length; i++) {
    if (tmp[i].b in o) {
      o[tmp[i].b].num++
    } else {
      o[tmp[i].b] = { num: 1, item: tmp[i] }
    }
  }
  for (let x in o) if (o[x].num === 1) result.push(o[x].item)
  return result
}
console.log(getdifferentArr(arr1, arr2))

// 2.如果是普通数组而不是对象数组,那就很简单了,方法很多,这里随便举两个案例
let result2 = []
let list2 = [1, 2, 3, 4, 5]
let val2 = [1, 2, 3]
result2 = list2.filter(number => !val2.includes(number))
console.log(result2)


var arr3 = [0, 1, 2, 3, 4, 5];
var arr4 = [0, 4, 6, 1, 3, 9];
function getArrDifference(arr3, arr4) {
  return arr3.concat(arr4).filter(function (v, i, arr) {
    return arr.indexOf(v) === arr.lastIndexOf(v);
  });
}
console.log(getArrDifference(arr3, arr4));

  // in运算符 如果指定的属性在指定的对象或其原型链中,则in 运算符返回true。

//补充一点,上述数组操作不乏很多for循环判断数组中是否存在这个元素或者是不存在,不过与其用for循环

//不如用map与some,every什么的,语法更加简洁

 

3.数组a,b,a的元素要在b中存在,不在a中存在的话,就放入新数组,最后得到一个新数组

那不就是b有a没有,b中的元素,那不就是把b中与a一样的元素剔除就行了

那把a看做一个枚举类型把?只要b中的元素在这个枚举之内就不push到新数组,否则就push到新数组

这个其实很简单,还是for循环判断罢了..............

// arr1有但arr2没有,也就是最后得到的新数组是 [ { a: 1, b: 3 }]
// 或者arr2有但arr1没有,也就是最后得到的新数组是 [ { a: 1, b: 4 }, { a: 1, b: 5 }]
let arr1 = [{ a: 1, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 3 }]
let arr2 = [{ a: 1, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 4 }, { a: 1, b: 5 }]

let newArr = []
arr1.map(el => {
  let someFlag = arr2.some(item => item.a == el.a && item.b == el.b)
  // 判断arr2中是否有当前这个el项
  // 如果有,那么则不push到新数组
  someFlag ? '' : newArr.push(el)
})
console.log(newArr)

newArr = []
arr2.map(el => {
  let someFlag = arr1.some(item => item.a == el.a && item.b == el.b)
  // 判断arr2中是否有当前这个el项
  // 如果有,那么则不push到新数组
  someFlag ? '' : newArr.push(el)
})
console.log(newArr)



// 补充一点,上述数组操作不乏很多for循环判断数组中是否存在这个元素或者是不存在,不过与其用for循环

// 不如用map与some,every什么的,语法更加简洁

4.一个数组按照另一个数组顺序排序

arr1 [2,1,3]

arr2 [1,2,3,4,5]

 

arr1.sort((prev,next)=>{

    return arr2.indexOf(prev)-arr2.indexOf(next)

})

这是arr1按照arr2排序

以及一些问题

发现一个小问题,之前用的sort排序两个数组,一个按照另一个排序,一直是少的那个以多的那个来排序,也确实应该这样,因为一般多的那个都是要排成的顺序,
但是一旦是多的那个要以少的那个排序就会有个问题,排是排了,但是没有移动位置,比如3 5 7 1 2以 2 1排序 排完后会是3 5 7 2 1而不是2 1 3 5 7

 

补充一点,上述数组操作不乏很多for循环判断数组中是否存在这个元素或者是不存在,不过与其用for循环

不如用map与some,every什么的,语法更加简洁

 

5.如果判断一个数组a是否属于数组b


// 判断a,b数组是否属于c数组
let a = [1, 2, 2, 3, 3, 4]
let b = [1, 2, 2, 3, 3, 10]
let c = [1, 2, 2, 3, 3, 4, 5, 6, 7, 8]

// 思路是,循环,在c中找到一个,就把a,b数组中的数据删掉,最后循环完后看看他们的长度是否为0
let aCopy = a.concat()
let bCopy = b.concat()

c.map(el => {
  let aIndex = aCopy.indexOf(el)
  if (aIndex >= 0) {
    aCopy.splice(aIndex, 1)
  }
  let bIndex = bCopy.indexOf(el)
  if (bIndex >= 0) {
    bCopy.splice(bIndex, 1)
  }
})
console.log(aCopy.length, bCopy.length)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
控制DHT11需要用到STM32的GPIO模块和定时器模块。具体步骤如下: 1. 配置GPIO口为输出模式,拉高输出电平,等待至少18ms,使DHT11处于空闲状态。 2. 将GPIO口配置为输入模式,等待DHT11响应,即DHT11输出低电平,持续80us左右,然后输出高电平,持续80us左右。 3. 接收DHT11的数据,DHT11共输出40个位,每个位的持续时间为50us左右,其中前8个位为湿度整数部分,接着8个位为湿度小数部分,再接着8个位为温度整数部分,接着8个位为温度小数部分,最后8个位为校验和。 4. 解析接收到的数据,计算湿度和温度的值。 以下是使用STM32控制DHT11的示例代码: ```c #include "dht11.h" #include "delay.h" #include "stm32f10x.h" #define DHT11_GPIO_PORT GPIOB #define DHT11_GPIO_PIN GPIO_Pin_0 void DHT11_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure); GPIO_SetBits(DHT11_GPIO_PORT, DHT11_GPIO_PIN); } u8 DHT11_Read_Data(u8 *dht_data) { u8 i, j; u8 data[5] = {0}; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure); GPIO_ResetBits(DHT11_GPIO_PORT, DHT11_GPIO_PIN); delay_ms(20); GPIO_SetBits(DHT11_GPIO_PORT, DHT11_GPIO_PIN); delay_us(40); GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure); if (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == Bit_RESET) { while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == Bit_RESET) ; while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == Bit_SET) ; for (j = 0; j < 5; j++) { for (i = 0; i < 8; i++) { while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == Bit_RESET) ; delay_us(40); if (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == Bit_SET) { data[j] |= (1 << (7 - i)); } while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == Bit_SET) ; } } if (data[4] == (data[0] + data[1] + data[2] + data[3])) { dht_data[0] = data[0]; dht_data[1] = data[2]; dht_data[2] = data[4]; return SUCCESS; } else { return ERROR; } } else { return ERROR; } } ``` 其中, `DHT11_Init()` 函数用于初始化DHT11, `DHT11_Read_Data()` 函数用于读取DHT11的数据,返回值为 `SUCCESS` 或 `ERROR`,表示读取是否成功,读取到的数据保存在 `u8 *dht_data` 数组中,依次为湿度整数部分、温度整数部分和校验和。在使用之前,需要先初始化时钟和延时函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值